Esempio n. 1
0
def notifyZopeApplicationOpenedSubscribers(event):
    """
    Re-fires the IDatabaseOpenedWithRoot notification to subscribers with an
    open handle to the application defined in the database.
    """
    db = event.database
    conn = db.open()
    try:
        app = conn.root()['Application']
        transact(notify)(ZopeApplicationOpenedEvent(app))
    finally:
        conn.close()
Esempio n. 2
0
def notifyZopeApplicationOpenedSubscribers(event):
    """
    Re-fires the IDatabaseOpenedWithRoot notification to subscribers with an
    open handle to the application defined in the database.
    """
    db = event.database
    conn = db.open()
    try:
        app = conn.root()['Application']
        transact(notify)(ZopeApplicationOpenedEvent(app))
    finally:
        conn.close()
Esempio n. 3
0
def scan_catalog(catalog, fix):
    """Scan through a catalog looking for broken references"""
    try:
        brains = catalog()
        sizeOfCatalog = len(brains)
        scannedCount = 0
        progressBarChunkSize = 1
        objectsWithIssues = []
        if not fix:
            print "Scanning   %s   [%s items]:" % (catalog.id, sizeOfCatalog)
        else:
            print "Fixing   %s   [%s items]:" % (catalog.id, sizeOfCatalog)

        if (sizeOfCatalog > 50):
            progressBarChunkSize = (sizeOfCatalog//50) + 1

        for brain in brains:
            if (scannedCount % progressBarChunkSize) == 0:
                sys.stdout.write('\r')
                chunkNumber = scannedCount // progressBarChunkSize
                sys.stdout.write("[%-50s] %d%%" % ('='*chunkNumber, 2*chunkNumber))
                sys.stdout.flush()
            scannedCount += 1
            try:
                testReference = brain.getObject()
            except Exception:
                objectsWithIssues.append(brain.getPath())
                if fix:
                    transact(catalog.uncatalog_object)(brain.getPath())

        # Finish off the execution progress bar since we're finished
        sys.stdout.write('\r')
        sys.stdout.write("[%-50s] %d%%" % ('='*50, 100))
        sys.stdout.flush()
        print ""

        if len(objectsWithIssues) == 0:
            summaryMsg.append("[Processed %s items in the %s catalog and found zero errors]"
                              % (scannedCount, catalog.id))
        else:
            summaryMsg.append("[Processed %s items in the %s catalog and found %s issues]"
                              % (scannedCount, catalog.id, len(objectsWithIssues)))
            for item in objectsWithIssues:
                summaryMsg.append("  %s" % (item))
    except AttributeError:
        print "{} not found.  skipping....".format(catalog)
    except Exception:
        raise
Esempio n. 4
0
    def applyDataMap(
        self,
        device,
        datamap,
        relname="",
        compname="",
        modname="",
        parentId="",
        commit=True,
    ):
        """Apply a datamap passed as a list of dicts through XML-RPC,
        A RelatinshipMap, or an ObjectMap

        Apply datamap to device. Return True if datamap changed device.

        The default value for commit is True for backwards-compatibility
        reasons. If you're a new caller to ApplyDataMap._applyData you should
        probably set commit to False and handle your own transactions.

        @type device: Device
        @param device: Device to be updated by a RelationshipMap,
            or parent device of an ObjectMap.
        @type datamap: RelationshipMap, ObjectMap
        @param datamap: map used to update the device, and its components
        @return: True if updated, False if not
        """
        log.debug('requested applyDataMap for device=%s', device)
        notify(DatamapAddEvent(self._dmd, datamap, device))
        if not device or _locked_from_updates(device):
            log.warn('device is locked from updates: device=%s', device)
            return False

        datamap = _validate_datamap(device,
                                    datamap,
                                    relname=relname,
                                    compname=compname,
                                    modname=modname,
                                    parentId=parentId)

        # Preprocess datamap, setting directive and diff
        if isinstance(datamap, RelationshipMap):
            datamap = _process_relationshipmap(datamap, device)
            if not datamap:
                return False
            adm_method = self._apply_relationshipmap
        else:
            adm_method = self._apply_incrementalmap

        # apply the changes
        if commit:
            result = transact(adm_method)(datamap, device)
        else:
            result = adm_method(datamap, device)

        # report the changes made
        result = self._report_changes(datamap, device)
        log.debug('applyDataMap result=%s', result)
        return result
    def remove(self, dmd, leaveObjects=False):
        # since this ZP added addition eventClasses, and zencatalogservice,
        # if is running, indexed them, the event catalog needs to be
        # cleaned up at removal
        super(ZenPack, self).remove(dmd, leaveObjects=leaveObjects)

        from ZODB.transact import transact
        brains = dmd.Events.eventClassSearch()
        for brain in brains:
            try:
                test_reference = brain.getObject()
                test_reference._p_deactivate()
            except Exception:
                object_path_string = brain.getPath()
                try:
                    transact(dmd.Events.eventClassSearch.uncatalog_object)(
                        object_path_string)
                except Exception as e:
                    pass
Esempio n. 6
0
def cleanZodb(dmd):
    global_catalog = dmd.zport.global_catalog

    uncat = transact(global_catalog.uncatalog_object)

    for brain in global_catalog():
        try:
            obj = brain.getObject()
        except Exception:
            log.warn("Found unresolvable path, deleting: %s", brain.getPath())
            uncat(brain.getPath())

    log.info("Finished scanning catalog")
Esempio n. 7
0
def cleanZodb(dmd):
    global_catalog = dmd.zport.global_catalog

    uncat = transact(global_catalog.uncatalog_object)

    for brain in global_catalog():
        try:
            obj = brain.getObject()
        except Exception:
            log.warn("Found unresolvable path, deleting: %s", brain.getPath())
            uncat(brain.getPath())

    log.info("Finished scanning catalog")
Esempio n. 8
0
    def _applyDataMap(self, device, datamap, commit=True):
        """Apply datamap to device. Return True if datamap changed device.

        The default value for commit is True for backwards-compatibility
        reasons. If you're a new caller to ApplyDataMap._applyData you should
        probably set commit to False and handle your own transactions.

        """
        self.zing_datamap_handler.add_datamap(device, datamap)
        if commit:
            result = transact(self._applyDataMapImpl)(device, datamap)
        else:
            result = self._applyDataMapImpl(device, datamap)
        return result
Esempio n. 9
0
    def _applyDataMap(self, device, datamap, commit=True):
        """Apply datamap to device. Return True if datamap changed device.

        The default value for commit is True for backwards-compatibility
        reasons. If you're a new caller to ApplyDataMap._applyData you should
        probably set commit to False and handle your own transactions.

        """
        self.zing_datamap_handler.add_datamap(device, datamap)
        if commit:
            result = transact(self._applyDataMapImpl)(device, datamap)
        else:
            result = self._applyDataMapImpl(device, datamap)
        return result
Esempio n. 10
0
    def _cleanCatalog(self, zport):
        global_catalog = self._getCatalog(zport)
        uncat = transact(global_catalog.uncatalog_object)

        for brain in global_catalog():
            try:
                obj = brain.getObject()
            except Exception:
                log.warn("Found unresolvable path, deleting: %s", brain.getPath())
                uncat(brain.getPath())

        log.info("Finished scanning catalog")

        return defer.succeed(None)
Esempio n. 11
0
    def _clean_catalog(self):
        drop_all_arguments()
        zc = ZenCatalog()
        dmd = zc.dmd
        zport = dmd.zport
        global_catalog = dmd.global_catalog
        uncat = transact(global_catalog.uncatalog_object)

        for brain in global_catalog():
            try:
                obj = brain.getObject()
            except KeyError:
                log.warn("Found unresolvable path, deleting: %s", brain.getPath())
                uncat(brain.getPath())
            except Exception:
                log.warn("Unexpected exception loading object %s. Skipping!", brain.getPath(), exc_info=True)

        log.info("Finished scanning catalog")
Esempio n. 12
0
def commit_in_batches(zc, buffer_consumer, inbox, buffer_size, counter=None):
    _commit_buffer = transact(buffer_consumer)

    def commit_buffer(buf):
        while True:
            try:
                return _commit_buffer(buf)
            except (AttributeError, ClientDisconnected, DisconnectedError):
                _reconnect(zc)
                continue

    buffer = []
    try:
        while True:
            try:
                element = inbox.get_nowait()
            except Empty:
                check_for_dead_parent()
                time.sleep(0.1)
                continue
            if element is None:
                # End of inbox. We're done here.
                break
            buffer.append(element)
            if len(buffer) >= buffer_size:
                delta = commit_buffer(buffer)
                if counter:
                    if delta is None:
                        delta = len(buffer)
                    counter.increment(delta)
                buffer = []
    finally:
        try:
            delta = commit_buffer(buffer)
        except BaseException:
            log.warn("Failed to commit some changes.", exc_info=True)
            for element in buffer:
                put_or_die(inbox, element)
        else:
            if counter:
                if delta is None:
                    delta = len(buffer)
                counter.increment(delta)
Esempio n. 13
0
def commit_in_batches(zc, buffer_consumer, inbox, buffer_size, counter=None):
    _commit_buffer = transact(buffer_consumer)

    def commit_buffer(buf):
        while True:
            try:
                return _commit_buffer(buf)
            except (AttributeError, ClientDisconnected, DisconnectedError):
                _reconnect(zc)
                continue

    buffer = []
    try:
        while True:
            try:
                element = inbox.get_nowait()
            except Empty:
                check_for_dead_parent()
                time.sleep(0.1)
                continue
            if element is None:
                # End of inbox. We're done here.
                break
            buffer.append(element)
            if len(buffer) >= buffer_size:
                delta = commit_buffer(buffer)
                if counter:
                    if delta is None:
                        delta = len(buffer)
                    counter.increment(delta)
                buffer = []
    finally:
        try:
            delta = commit_buffer(buffer)
        except BaseException:
            log.warn("Failed to commit some changes.", exc_info=True)
            for element in buffer:
                put_or_die(inbox, element)
        else:
            if counter:
                if delta is None:
                    delta = len(buffer)
                counter.increment(delta)
Esempio n. 14
0
    def _clean_catalog(self):
        drop_all_arguments()
        zc = ZenCatalog()
        dmd = zc.dmd
        zport = dmd.zport
        global_catalog = dmd.global_catalog
        uncat = transact(global_catalog.uncatalog_object)

        for brain in global_catalog():
            try:
                obj = brain.getObject()
            except KeyError:
                log.warn("Found unresolvable path, deleting: %s",
                         brain.getPath())
                uncat(brain.getPath())
            except Exception:
                log.warn("Unexpected exception loading object %s. Skipping!",
                         brain.getPath(),
                         exc_info=True)

        log.info("Finished scanning catalog")
Esempio n. 15
0
 def quickstartWizardFinished(self):
     # a place to hook up anything that needs to happen
     app = self.context.dmd.primaryAq().getParentNode().getParentNode()
     transact(notify)(QuickstartWizardFinishedEvent(app))
     return DirectResponse.succeed()
Esempio n. 16
0
    def setProdState(self, state, ending=False, batchSize=None,
                     inTransaction=False):
        """
        At any one time there is one production state for each device to be in,
        and that is the state that is the most 'blacked out' in all of the active
        maintenance windows affecting that device.  When the last maintenance
        window affecting a device has ended, the original production state of the
        device is used to determine the end state of the device.

        Maintenance windows are processed by zenjobs in batch so the ordering
        of when two maintenance windows that end at the same time get processed
        is non-deterministic.  Since there is only one stop production state now,
        this is not an issue.

        @parameter state: hint from the maint window about device's start or stop state
        @type state: integer
        @parameter ending: are we ending a maintenance window?
        @type ending: boolean
        @parameter batchSize: number of processed devices per separate transaction
        @type batchSize: integer
        @parameter inTransaction: process each batch in separate transaction
        @type inTransaction: boolean
        """
        # Note: self.begin() starts our window before we get called, so the
        #       following takes into account our window state too.
        #       Conversely, self.end() ends the window before calling this code.
        devices = self.fetchDevices()
        minDevProdStates = self.fetchDeviceMinProdStates(devices)

        def _setProdState(devices_batch):
            for device in devices_batch:
                # In case we try to move Component Group into MW
                # some of objects in CG may not have production state
                # we skip them.
                if ending:
                    # Note: If no maintenance windows apply to a device, then the
                    #       device won't exist in minDevProdStates
                    # This takes care of the case where there are still active
                    # maintenance windows.
                    minProdState = minDevProdStates.get(device.id,
                                                device.getPreMWProductionState())

                elif device.id in minDevProdStates:
                    minProdState = minDevProdStates[device.id]

                else: # This is impossible for us to ever get here as minDevProdStates
                      # has been added by self.fetchDeviceMinProdStates()
                    log.error("The device %s does not appear in any maintenance"
                              " windows (including %s -- which is just starting).",
                              device.id, self.displayName())
                    continue

                # ZEN-13197: skip decommissioned devices
                if device.getPreMWProductionState() and device.getPreMWProductionState() < 300:
                    continue

                self._p_changed = 1
                # Changes the current state for a device, but *not*
                # the preMWProductionState
                oldProductionState = self.dmd.convertProdState(device.getProductionState())
                # When MW ends Components will acquire production state from device
                if not minProdState:
                    newProductionState = "Acquired from parent"
                else:
                    newProductionState = self.dmd.convertProdState(minProdState)
                log.info("MW %s changes %s's production state from %s to %s",
                         self.displayName(), device.id, oldProductionState,
                         newProductionState)
                audit('System.Device.Edit', device, starting=str(not ending),
                    maintenanceWindow=self.displayName(),
                    productionState=newProductionState,
                    oldData_={'productionState':oldProductionState})
                if minProdState is None:
                    device.resetProductionState()
                else:
                    device.setProdState(minProdState, maintWindowChange=True)

        if inTransaction:
            processFunc = transact(_setProdState)
            # Commit transaction as errors during batch processing may
            # abort transaction and changes to the object will not be saved.
            transaction.commit()
        else:
            processFunc = _setProdState

        if batchSize:
            for i in xrange(0, len(devices), batchSize):
                log.info('MW %s processing batch #%s', self.displayName(),
                         i / batchSize + 1)
                processFunc(devices[i:i + batchSize])
        else:
            processFunc(devices)
Esempio n. 17
0
 def _setSnmpLastCollection(self, device):
     transactional = transact(device.setSnmpLastCollection)
     return self._do_with_retries(transactional)
Esempio n. 18
0
def catalog_the_things(worker_id, inbox, trash, buffer_size, permissions_only, print_progress=None):
    # We don't import this above, because it didn't exist prior to 4.2.
    # It's safe to import here, because we only get here if the CatalogService
    # is installed, which didn't exist until 4.2.
    from Products.Zuul.catalog.global_catalog import initializeGlobalCatalog

    ignore_interruptions()
    drop_all_arguments()
    zc             = ZenCatalog()
    dmd            = zc.dmd
    zport          = dmd.getPhysicalRoot().zport
    global_catalog = _get_global_catalog(zport)
    catalog_id     = local_catalog_id(worker_id)

    def _create_local_catalog():
        local_catalog  = global_catalog.__class__()
        initializeGlobalCatalog(local_catalog)
        try:
           zport._delObject(catalog_id)
        except:
           pass
        zport._setObject(catalog_id, local_catalog)

    create_local_catalog = transact(_create_local_catalog, retries=100)
    create_local_catalog()
    local_catalog  = getattr(zport, catalog_id, None)
    catalog        = local_catalog._catalog
    counter        = ProgressCounter(print_progress=print_progress)

    def _catalog_one(primary_path):
        try:
            obj = dmd.unrestrictedTraverse(primary_path)
        except (AttributeError, ClientDisconnected, DisconnectedError):
            raise
        except KeyError:
            log.debug("Could not load object: %s", primary_path)
            put_or_die(trash, primary_path)
            return False
        except Exception:
            log.warn("Unexpected exception loading object %s. Skipping!", primary_path, exc_info=True)
            return False
        if obj is None:
            log.debug("%s does not exist", primary_path)
            put_or_die(trash, primary_path)
            return False
        try:
            uid = global_catalog._catalog.uids.get(primary_path, None)
            if uid is not None:
                catalog.uids[primary_path] = uid
                catalog.paths[uid] = global_catalog._catalog.paths.get(uid, None)
                catalog.data[uid] = global_catalog._catalog.data.get(uid, None)
            if permissions_only:
                catalog.catalog_object(obj, update_metadata=False,
                                            idxs=("allowedRolesAndUsers",))
            else:
                # We intentionally don't do legacy indexing:
                # if hasattr(obj, 'index_object'): obj.index_object()
                catalog.catalog_object(obj)
        except (AttributeError, ClientDisconnected, DisconnectedError):
            raise
        except Exception:
            log.info("Error cataloging object %s. Skipping", primary_path,
                     exc_info=(log.isEnabledFor(logging.DEBUG)))
            return False
        return True

    def _catalog_several(primary_paths):
        dmd._p_jar.sync()
        count = 0
        for primary_path in primary_paths:
            if _catalog_one(primary_path):
                count += 1
        return count

    commit_in_batches(zc, _catalog_several, inbox, buffer_size, counter)
Esempio n. 19
0
def scan_catalog(catalogObject, fix, dmd, log, createEvents):
    """Scan through a catalog looking for broken references"""

    # Fix for ZEN-14717 (only for global_catalog)
    if (catalogObject.prettyName == 'global_catalog'):
        global_catalog_paths_to_uids(catalogObject, fix, dmd, log, createEvents)

    catalog = eval(catalogObject.dmdPath)
    catalogObject.initialSize = len(catalog)

    print("[%s] Examining %-35s (%d Objects)" %
          (time.strftime("%Y-%m-%d %H:%M:%S"), catalogObject.prettyName, catalogObject.initialSize))
    log.info("Examining %s catalog with %d objects" % (catalogObject.prettyName, catalogObject.initialSize))

    currentCycle = 0

    while (currentCycle < maxCycles):
        currentCycle += 1
        catalogObject.runResults[currentCycle] = {'itemCount': ZenToolboxUtils.Counter(0),
                                                  'errorCount': ZenToolboxUtils.Counter(0),
                                                  'repairCount': ZenToolboxUtils.Counter(0)
                                                  }
        log.info("Beginning cycle %d for catalog %s" % (currentCycle, catalogObject.prettyName))
        scan_progress_message(False, fix, currentCycle, catalogObject.prettyName, 0, 0, log)

        try:
            brains = eval(catalogObject.dmdPath)()
        except Exception:
            raise

        catalogSize = len(brains)
        if (catalogSize > 50):
            progressBarChunkSize = (catalogSize//50) + 1
        else:
            progressBarChunkSize = 1

        for brain in brains:
            catalogObject.runResults[currentCycle]['itemCount'].increment()
            if (catalogObject.runResults[currentCycle]['itemCount'].value() % progressBarChunkSize) == 0:
                chunkNumber = catalogObject.runResults[currentCycle]['itemCount'].value() // progressBarChunkSize
                scan_progress_message(False, fix, currentCycle, catalogObject.prettyName,
                                      catalogObject.runResults[currentCycle]['errorCount'].value(), chunkNumber, log)
            try:
                testReference = brain.getObject()
                testReference._p_deactivate()
            except Exception:
                catalogObject.runResults[currentCycle]['errorCount'].increment()
                objectPathString = brain.getPath()
                log.error("Catalog %s contains broken object %s" % (catalogObject.prettyName, objectPathString))
                if fix:
                    log.info("Attempting to uncatalog %s" % (objectPathString))
                    try:
                        catalogObject.runResults[currentCycle]['repairCount'].increment()
                        transact(catalog.uncatalog_object)(objectPathString)
                    except Exception as e:
                        log.exception(e)

        # Final transaction.abort() to try and free up used memory
        log.debug("Calling transaction.abort() to minimize memory footprint")
        transaction.abort()

        scan_progress_message(True, fix, currentCycle, catalogObject.prettyName,
                              catalogObject.runResults[currentCycle]['errorCount'].value(), chunkNumber, log)

        if fix:
            if catalogObject.runResults[currentCycle]['errorCount'].value() == 0:
                break
            if currentCycle > 1:
                if catalogObject.runResults[currentCycle]['errorCount'].value() == catalogObject.runResults[currentCycle-1]['errorCount'].value():
                    break

    if createEvents:
        scriptName = os.path.basename(__file__).split('.')[0]
        eventMsg = ""
        for cycleID in catalogObject.runResults.keys():
            eventMsg += "Cycle %d scanned %d items, found %d errors and attempted %d repairs\n" % \
                        (cycleID, catalogObject.runResults[cycleID]['itemCount'].value(),
                         catalogObject.runResults[cycleID]['errorCount'].value(),
                         catalogObject.runResults[cycleID]['repairCount'].value())
        if not catalogObject.runResults[currentCycle]['errorCount'].value():
            eventSeverity = 1
            if currentCycle == 1:
                eventSummaryMsg = "'%s' - No Errors Detected (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.initialSize)
            else:
                eventSummaryMsg = "'%s' - No Errors Detected [--fix was successful] (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.initialSize)
        else:
            eventSeverity = 4
            if fix:
                eventSummaryMsg = "'%s' - %d Errors Remain after --fix [consult log file]  (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)
            else:
                eventSummaryMsg = "'%s' - %d Errors Detected [run with --fix]  (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)

        log.debug("Creating event with %s, %s" % (eventSummaryMsg, eventSeverity))
        ZenToolboxUtils.send_summary_event(
            eventSummaryMsg, eventSeverity,
            scriptName, catalogObject.prettyName,
            documentationURL, dmd, eventMsg
        )

    return (catalogObject.runResults[currentCycle]['errorCount'].value() != 0)
Esempio n. 20
0
def scan_catalog(catalog_name, catalog_list, fix, max_cycles, dmd, log):
    """Scan through a catalog looking for broken references"""

    catalog = catalog_list[0]
    initial_catalog_size = catalog_list[1]

    print("[%s] Examining %-35s (%d Objects)" %
          (time.strftime("%Y-%m-%d %H:%M:%S"), catalog_name,
           initial_catalog_size))
    log.info("Examining %s catalog with %d objects" %
             (catalog_name, initial_catalog_size))

    number_of_issues = -1
    current_cycle = 0
    if not fix:
        max_cycles = 1

    while ((current_cycle < max_cycles) and (number_of_issues != 0)):
        number_of_issues = 0
        current_cycle += 1
        if (fix):
            log.info("Beginning cycle %d for catalog %s" %
                     (current_cycle, catalog_name))
        scanned_count = 0
        progress_bar_chunk_size = 1

        # ZEN-12165: show progress bar immediately before 'for' time overhead, before loading catalog
        scan_progress_message(False, fix, current_cycle, catalog_name, 0, 0,
                              log)

        try:
            brains = catalog()
            catalog_size = len(brains)
            if (catalog_size > 50):
                progress_bar_chunk_size = (catalog_size // 50) + 1
        except Exception:
            raise

        for brain in brains:
            scanned_count += 1
            if (scanned_count % progress_bar_chunk_size) == 0:
                chunk_number = scanned_count // progress_bar_chunk_size
                scan_progress_message(False, fix, current_cycle, catalog_name,
                                      number_of_issues, chunk_number, log)
            try:
                test_reference = brain.getObject()
                test_reference._p_deactivate()
            except Exception:
                number_of_issues += 1
                object_path_string = brain.getPath()
                log.error("Catalog %s contains broken object %s" %
                          (catalog_name, object_path_string))
                if fix:
                    log.info("Attempting to uncatalog %s" %
                             (object_path_string))
                    try:
                        transact(catalog.uncatalog_object)(object_path_string)
                    except Exception as e:
                        log.exception(e)

        # Final transaction.abort() to try and free up used memory
        log.debug("Calling transaction.abort() to minimize memory footprint")
        transaction.abort()

        scan_progress_message(True, fix, current_cycle, catalog_name,
                              number_of_issues, chunk_number, log)

    if number_of_issues > 0:
        return True
    return False
Esempio n. 21
0
def catalog_the_things(worker_id,
                       inbox,
                       trash,
                       buffer_size,
                       permissions_only,
                       print_progress=None):
    # We don't import this above, because it didn't exist prior to 4.2.
    # It's safe to import here, because we only get here if the CatalogService
    # is installed, which didn't exist until 4.2.
    from Products.Zuul.catalog.global_catalog import initializeGlobalCatalog

    ignore_interruptions()
    drop_all_arguments()
    zc = ZenCatalog()
    dmd = zc.dmd
    zport = dmd.getPhysicalRoot().zport
    global_catalog = _get_global_catalog(zport)
    catalog_id = local_catalog_id(worker_id)

    def _create_local_catalog():
        local_catalog = global_catalog.__class__()
        initializeGlobalCatalog(local_catalog)
        try:
            zport._delObject(catalog_id)
        except:
            pass
        zport._setObject(catalog_id, local_catalog)

    create_local_catalog = transact(_create_local_catalog, retries=100)
    create_local_catalog()
    local_catalog = getattr(zport, catalog_id, None)
    catalog = local_catalog._catalog
    counter = ProgressCounter(print_progress=print_progress)

    def _catalog_one(primary_path):
        try:
            obj = dmd.unrestrictedTraverse(primary_path)
        except (AttributeError, ClientDisconnected, DisconnectedError):
            raise
        except KeyError:
            log.debug("Could not load object: %s", primary_path)
            put_or_die(trash, primary_path)
            return False
        except Exception:
            log.warn("Unexpected exception loading object %s. Skipping!",
                     primary_path,
                     exc_info=True)
            return False
        if obj is None:
            log.debug("%s does not exist", primary_path)
            put_or_die(trash, primary_path)
            return False
        try:
            uid = global_catalog._catalog.uids.get(primary_path, None)
            if uid is not None:
                catalog.uids[primary_path] = uid
                catalog.paths[uid] = global_catalog._catalog.paths.get(
                    uid, None)
                catalog.data[uid] = global_catalog._catalog.data.get(uid, None)
            if permissions_only:
                catalog.catalog_object(obj,
                                       update_metadata=False,
                                       idxs=("allowedRolesAndUsers", ))
            else:
                # We intentionally don't do legacy indexing:
                # if hasattr(obj, 'index_object'): obj.index_object()
                catalog.catalog_object(obj)
        except (AttributeError, ClientDisconnected, DisconnectedError):
            raise
        except Exception:
            log.info("Error cataloging object %s. Skipping",
                     primary_path,
                     exc_info=(log.isEnabledFor(logging.DEBUG)))
            return False
        return True

    def _catalog_several(primary_paths):
        dmd._p_jar.sync()
        count = 0
        for primary_path in primary_paths:
            if _catalog_one(primary_path):
                count += 1
        return count

    commit_in_batches(zc, _catalog_several, inbox, buffer_size, counter)
Esempio n. 22
0
 def wrapper(obj, *args, **kwargs):
     if obj.options.nocommit:
         return f.__call__(obj, *args, **kwargs)
     else:
         return transact(f).__call__(obj, *args, **kwargs)
 def transactional(f):
     return f if self.options.nocommit else transact(f)
Esempio n. 24
0
 def transactional(f):
     return f if self.options.nocommit else transact(f)
Esempio n. 25
0
def scan_catalog(catalog_name, catalog_list, fix, max_cycles, dmd, log, create_events):
    """Scan through a catalog looking for broken references"""

    # Fix for ZEN-14717 (only for global_catalog)
    if (catalog_name == 'global_catalog'):
        global_catalog_rids(catalog_name, catalog_list, fix, max_cycles, dmd, log, create_events)

    catalog = catalog_list[0]
    initial_catalog_size = catalog_list[1]
    number_of_issues = -1
    current_cycle = 0
    if not fix:
        max_cycles = 1

    print("[%s] Examining %-35s (%d Objects)" %
          (time.strftime("%Y-%m-%d %H:%M:%S"), catalog_name, initial_catalog_size))
    log.info("Examining %s catalog with %d objects" % (catalog_name, initial_catalog_size))

    while ((current_cycle < max_cycles) and (number_of_issues != 0)):
        number_of_issues = 0
        current_cycle += 1
        if (fix):
            log.info("Beginning cycle %d for catalog %s" % (current_cycle, catalog_name))
        scanned_count = 0
        progress_bar_chunk_size = 1

        # ZEN-12165: show progress bar immediately before 'for' time overhead, before loading catalog
        scan_progress_message(False, fix, current_cycle, catalog_name, 0, 0, log)

        try:
            brains = catalog()
            catalog_size = len(brains)
            if (catalog_size > 50):
                progress_bar_chunk_size = (catalog_size//50) + 1
        except Exception:
            raise

        for brain in brains:
            scanned_count += 1
            if (scanned_count % progress_bar_chunk_size) == 0:
                chunk_number = scanned_count // progress_bar_chunk_size
                scan_progress_message(False, fix, current_cycle, catalog_name, number_of_issues, chunk_number, log)
            try:
                test_reference = brain.getObject()
                test_reference._p_deactivate()
            except Exception:
                number_of_issues += 1
                object_path_string = brain.getPath()
                log.error("Catalog %s contains broken object %s" % (catalog_name, object_path_string))
                if fix:
                    log.info("Attempting to uncatalog %s" % (object_path_string))
                    try:
                        transact(catalog.uncatalog_object)(object_path_string)
                    except Exception as e:
                        log.exception(e)

        # Final transaction.abort() to try and free up used memory
        log.debug("Calling transaction.abort() to minimize memory footprint")
        transaction.abort()

        scan_progress_message(True, fix, current_cycle, catalog_name, number_of_issues, chunk_number, log)

    if create_events:
        if number_of_issues > 0:
            eventSummaryMsg = "'%s' - %d Error(s) Detected (%d total items)" % (catalog_name, number_of_issues, initial_catalog_size)
            eventSeverity = 4  
        else:
            eventSummaryMsg = "'%s' - No Errors Detected (%d total items)" % (catalog_name, initial_catalog_size)
            eventSeverity = 1
     
        dmd.ZenEventManager.sendEvent({
            'device'        : 'localhost',
            'summary'       : eventSummaryMsg,
            'message'       : eventSummaryMsg,
            'component'     : 'zenoss_toolbox',
            'severity'      : eventSeverity,
            'eventClass'    : '/Status',
            'eventKey'      : "%s" % (catalog_name),
            'dedupid'       : "zenoss_toolbox_zencatalogscan.%s" % (catalog_name),
            'eventClassKey' : "zenoss_toolbox_zencatalogscan",
            'details'       : "Consult https://support.zenoss.com/hc/en-us/articles/203118075 for additional information"
        })

    return (number_of_issues != 0)
Esempio n. 26
0
 def _setSnmpLastCollection(self, device):
     transactional = transact(device.setSnmpLastCollection)
     return self._do_with_retries(transactional)
Esempio n. 27
0
 def quickstartWizardFinished(self):
     # a place to hook up anything that needs to happen
     app = self.context.dmd.primaryAq().getParentNode().getParentNode()
     transact(notify)(QuickstartWizardFinishedEvent(app))
     return DirectResponse.succeed()
Esempio n. 28
0
 def wrapper(obj, *args, **kwargs):
     if obj.options.nocommit:
         return f.__call__(obj, *args, **kwargs)
     else:
         return transact(f).__call__(obj, *args, **kwargs)
Esempio n. 29
0
def scan_catalog(catalogObject, fix, dmd, log, createEvents):
    """Scan through a catalog looking for broken references"""

    # Fix for ZEN-14717 (only for global_catalog)
    if (catalogObject.prettyName == 'global_catalog'):
        global_catalog_paths_to_uids(catalogObject, fix, dmd, log,
                                     createEvents)

    catalog = eval(catalogObject.dmdPath)
    catalogObject.initialSize = len(catalog)

    print("[%s] Examining %-35s (%d Objects)" %
          (time.strftime("%Y-%m-%d %H:%M:%S"), catalogObject.prettyName,
           catalogObject.initialSize))
    log.info("Examining %s catalog with %d objects" %
             (catalogObject.prettyName, catalogObject.initialSize))

    currentCycle = 0

    while (currentCycle < maxCycles):
        currentCycle += 1
        catalogObject.runResults[currentCycle] = {
            'itemCount': ZenToolboxUtils.Counter(0),
            'errorCount': ZenToolboxUtils.Counter(0),
            'repairCount': ZenToolboxUtils.Counter(0)
        }
        log.info("Beginning cycle %d for catalog %s" %
                 (currentCycle, catalogObject.prettyName))
        scan_progress_message(False, fix, currentCycle,
                              catalogObject.prettyName, 0, 0, log)

        try:
            brains = eval(catalogObject.dmdPath)()
        except Exception:
            raise

        catalogSize = len(brains)
        if (catalogSize > 50):
            progressBarChunkSize = (catalogSize // 50) + 1
        else:
            progressBarChunkSize = 1

        for brain in brains:
            catalogObject.runResults[currentCycle]['itemCount'].increment()
            if (catalogObject.runResults[currentCycle]['itemCount'].value() %
                    progressBarChunkSize) == 0:
                chunkNumber = catalogObject.runResults[currentCycle][
                    'itemCount'].value() // progressBarChunkSize
                scan_progress_message(
                    False, fix, currentCycle, catalogObject.prettyName,
                    catalogObject.runResults[currentCycle]
                    ['errorCount'].value(), chunkNumber, log)
            try:
                testReference = brain.getObject()
                testReference._p_deactivate()
            except Exception:
                catalogObject.runResults[currentCycle]['errorCount'].increment(
                )
                objectPathString = brain.getPath()
                log.error("Catalog %s contains broken object %s" %
                          (catalogObject.prettyName, objectPathString))
                if fix:
                    log.info("Attempting to uncatalog %s" % (objectPathString))
                    try:
                        catalogObject.runResults[currentCycle][
                            'repairCount'].increment()
                        transact(catalog.uncatalog_object)(objectPathString)
                    except Exception as e:
                        log.exception(e)

        # Final transaction.abort() to try and free up used memory
        log.debug("Calling transaction.abort() to minimize memory footprint")
        transaction.abort()

        scan_progress_message(
            True, fix, currentCycle, catalogObject.prettyName,
            catalogObject.runResults[currentCycle]['errorCount'].value(),
            chunkNumber, log)

        if fix:
            if catalogObject.runResults[currentCycle]['errorCount'].value(
            ) == 0:
                break
            if currentCycle > 1:
                if catalogObject.runResults[currentCycle]['errorCount'].value(
                ) == catalogObject.runResults[currentCycle -
                                              1]['errorCount'].value():
                    break

    if createEvents:
        scriptName = os.path.basename(__file__).split('.')[0]
        eventMsg = ""
        for cycleID in catalogObject.runResults.keys():
            eventMsg += "Cycle %d scanned %d items, found %d errors and attempted %d repairs\n" % \
                        (cycleID, catalogObject.runResults[cycleID]['itemCount'].value(),
                         catalogObject.runResults[cycleID]['errorCount'].value(),
                         catalogObject.runResults[cycleID]['repairCount'].value())
        if not catalogObject.runResults[currentCycle]['errorCount'].value():
            eventSeverity = 1
            if currentCycle == 1:
                eventSummaryMsg = "'%s' - No Errors Detected (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.initialSize)
            else:
                eventSummaryMsg = "'%s' - No Errors Detected [--fix was successful] (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.initialSize)
        else:
            eventSeverity = 4
            if fix:
                eventSummaryMsg = "'%s' - %d Errors Remain after --fix [consult log file]  (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)
            else:
                eventSummaryMsg = "'%s' - %d Errors Detected [run with --fix]  (%d total items)" % \
                                   (catalogObject.prettyName, catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)

        log.debug("Creating event with %s, %s" %
                  (eventSummaryMsg, eventSeverity))
        ZenToolboxUtils.send_summary_event(eventSummaryMsg, eventSeverity,
                                           scriptName,
                                           catalogObject.prettyName,
                                           documentationURL, dmd, eventMsg)

    return (catalogObject.runResults[currentCycle]['errorCount'].value() != 0)
Esempio n. 30
0
    def setProdState(self,
                     state,
                     ending=False,
                     batchSize=None,
                     inTransaction=False):
        """
        At any one time there is one production state for each device to be in,
        and that is the state that is the most 'blacked out' in all of the active
        maintenance windows affecting that device.  When the last maintenance
        window affecting a device has ended, the original production state of the
        device is used to determine the end state of the device.

        Maintenance windows are processed by zenjobs in batch so the ordering
        of when two maintenance windows that end at the same time get processed
        is non-deterministic.  Since there is only one stop production state now,
        this is not an issue.

        @parameter state: hint from the maint window about device's start or stop state
        @type state: integer
        @parameter ending: are we ending a maintenance window?
        @type ending: boolean
        @parameter batchSize: number of processed devices per separate transaction
        @type batchSize: integer
        @parameter inTransaction: process each batch in separate transaction
        @type inTransaction: boolean
        """
        # Note: self.begin() starts our window before we get called, so the
        #       following takes into account our window state too.
        #       Conversely, self.end() ends the window before calling this code.
        devices = self.fetchDevices()
        unchangedDevices = []
        minDevProdStates = self.fetchDeviceMinProdStates(devices)

        def _setProdState(devices_batch):
            for device in devices_batch:
                guid = IGlobalIdentifier(device).getGUID()
                # In case we try to move Component Group into MW
                # some of objects in CG may not have production state
                # we skip them.
                if ending:
                    # Note: If no maintenance windows apply to a device, then the
                    #       device won't exist in minDevProdStates
                    # This takes care of the case where there are still active
                    # maintenance windows.
                    minProdState = minDevProdStates.get(
                        guid, device.getPreMWProductionState())

                elif guid in minDevProdStates:
                    minProdState = minDevProdStates[guid]

                else:  # This is impossible for us to ever get here as minDevProdStates
                    # has been added by self.fetchDeviceMinProdStates()
                    log.error(
                        "The device %s does not appear in any maintenance"
                        " windows (including %s -- which is just starting).",
                        device.id, self.displayName())
                    continue

                # ZEN-13197: skip decommissioned devices
                if device.getPreMWProductionState(
                ) and device.getPreMWProductionState() < 300:
                    continue

                self._p_changed = 1
                # Changes the current state for a device, but *not*
                # the preMWProductionState
                oldProductionState = self.dmd.convertProdState(
                    device.getProductionState())
                # When MW ends Components will acquire production state from device
                if not minProdState:
                    newProductionState = "Acquired from parent"
                else:
                    newProductionState = self.dmd.convertProdState(
                        minProdState)
                log.info("MW %s changes %s's production state from %s to %s",
                         self.displayName(), device.id, oldProductionState,
                         newProductionState)
                audit('System.Device.Edit',
                      device,
                      starting=str(not ending),
                      maintenanceWindow=self.displayName(),
                      productionState=newProductionState,
                      oldData_={'productionState': oldProductionState})
                if minProdState is None:
                    device.resetProductionState()
                else:
                    device.setProdState(minProdState, maintWindowChange=True)

        def retrySingleDevices(devices_batch):
            log.warn("Retrying devices individually")
            for dev in devices_batch:
                try:
                    processFunc([dev])
                except Exception:
                    log.exception(
                        "The production stage change for %s raised the exception.",
                        dev)
                    unchangedDevices.append(dev)

        def processBatchOfDevices(devices, batchSize):
            for i in xrange(0, len(devices), batchSize):
                log.info('MW %s processing batch #%s', self.displayName(),
                         i / batchSize + 1)
                dev_chunk = devices[i:i + batchSize]
                try:
                    processFunc(dev_chunk)
                except (ConflictError, POSKeyError, ReadConflictError) as e:
                    log.warn(
                        "While processing batch of %d devices exception was raised. %s",
                        len(dev_chunk), e)
                    retrySingleDevices(dev_chunk)
                except Exception:
                    # We're expecting ConflictError, POSKeyError, ReadConflictError, and handle them with retries
                    # production state change. All other exceptions are an unexplored area that should be properly
                    # processed in the future instead of the stub below.
                    log.exception("Unexpected Exception encountered")
                    retrySingleDevices(dev_chunk)

        if inTransaction:
            processFunc = transact(_setProdState)
            # Commit transaction as errors during batch processing may
            # abort transaction and changes to the object will not be saved.
            transaction.commit()
        else:
            processFunc = _setProdState

        # Adding exception handling for the following:
        # ConflictError, POSKeyError and ReadConflictError.
        #
        # If any of the listed exceptions are encountered, we will retry
        # devices in the batch individually.  If batchSize isn't
        # specified and we encounter one of these exceptions, we will
        # then specify a batch size and retry the devices in batches.
        # If there are exceptions in these batches, we will retry the
        # devices individually.  This will ensure that maintenance
        # windows as a whole do not fail due to these exceptions.
        # Fixes ZEN-31805.
        if batchSize:
            processBatchOfDevices(devices, batchSize)
        else:
            try:
                processFunc(devices)
            except (ConflictError, POSKeyError, ReadConflictError) as e:
                log.warn(
                    "Exception encountered and no batchSize specified. "
                    "%s. Retrying in batches.", e)
                processBatchOfDevices(devices, 10)
            except Exception:
                log.exception("Unexpected Exception encountered")
                processBatchOfDevices(devices, 10)

        if unchangedDevices:
            log.error("Unable to change Production State on: %s",
                      unchangedDevices)