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)
def main():
    """Scans catalogs for broken references.  If --fix, attempts to remove broken references."""

    executionStart = time.time()
    scriptName = os.path.basename(__file__).split('.')[0]
    parser = ZenToolboxUtils.parse_options(
        scriptVersion, scriptName + scriptSummary + documentationURL)
    # Add in any specific parser arguments for %scriptName
    parser.add_argument("-f",
                        "--fix",
                        action="store_true",
                        default=False,
                        help="attempt to remove any invalid references")
    parser.add_argument("-n",
                        "--cycles",
                        action="store",
                        default="12",
                        type=int,
                        help="maximum times to cycle (with --fix, <= 12)")
    parser.add_argument("-l",
                        "--list",
                        action="store_true",
                        default=False,
                        help="output all supported catalogs")
    parser.add_argument("-c",
                        "--catalog",
                        action="store",
                        default="",
                        help="only scan/fix specified catalog")
    cliOptions = vars(parser.parse_args())
    log, logFileName = ZenToolboxUtils.configure_logging(
        scriptName, scriptVersion, cliOptions['tmpdir'])
    log.info("Command line options: %s" % (cliOptions))
    if cliOptions['debug']:
        log.setLevel(logging.DEBUG)

    print "\n[%s] Initializing %s v%s (detailed log at %s)" % \
          (time.strftime("%Y-%m-%d %H:%M:%S"), scriptName, scriptVersion, logFileName)

    # Attempt to get the zenoss.toolbox lock before any actions performed
    if not ZenToolboxUtils.get_lock("zenoss.toolbox", log):
        sys.exit(1)

    # Obtain dmd ZenScriptBase connection
    dmd = ZenScriptBase(noopts=True, connect=True).dmd
    log.debug("ZenScriptBase connection obtained")

    anyIssue = False
    global maxCycles
    if cliOptions['fix']:
        if cliOptions['cycles'] > 12:
            maxCycles = 12
        else:
            maxCycles = cliOptions['cycles']
    else:
        maxCycles = 1

    validCatalogList = build_catalog_list(dmd, log)
    if cliOptions['list']:
        print "List of supported Zenoss catalogs to examine:\n"
        for item in validCatalogList:
            print item.prettyName
        log.info(
            "Zencatalogscan finished - list of supported catalogs output to CLI"
        )
    else:
        if cliOptions['catalog']:
            foundItem = False
            for item in validCatalogList:
                if cliOptions['catalog'] == item.prettyName:
                    foundItem = True
                    anyIssue = scan_catalog(item, cliOptions['fix'], dmd, log,
                                            not cliOptions['skipEvents'])
            if not foundItem:
                print("Catalog '%s' unrecognized - unable to scan" %
                      (cliOptions['catalog']))
                log.error("CLI input '%s' doesn't match recognized catalogs" %
                          (cliOptions['catalog']))
                exit(1)
        else:
            for item in validCatalogList:
                anyIssue = scan_catalog(
                    item, cliOptions['fix'], dmd, log,
                    not cliOptions['skipEvents']) or anyIssue

    # Print final status summary, update log file with termination block
    print("\n[%s] Execution finished in %s\n" %
          (time.strftime("%Y-%m-%d %H:%M:%S"),
           datetime.timedelta(seconds=int(time.time() - executionStart))))
    log.info("zencatalogscan completed in %1.2f seconds" %
             (time.time() - executionStart))
    log.info("############################################################")

    if not cliOptions['skipEvents']:
        if anyIssue:
            eventSummaryMsg = "%s encountered errors (took %1.2f seconds)" % (
                scriptName, (time.time() - executionStart))
            eventSeverity = 4
        else:
            eventSummaryMsg = "%s completed without errors (took %1.2f seconds)" % (
                scriptName, (time.time() - executionStart))
            eventSeverity = 2

        ZenToolboxUtils.send_summary_event(eventSummaryMsg, eventSeverity,
                                           scriptName, "executionStatus",
                                           documentationURL, dmd)

    if anyIssue and not cliOptions['fix']:
        print("** WARNING ** Issues were detected - Consult KB article at")
        print("      https://support.zenoss.com/hc/en-us/articles/203118075\n")
        sys.exit(1)
    else:
        sys.exit(0)
def main():
    """Scans catalogs for broken references.  If --fix, attempts to remove broken references."""

    executionStart = time.time()
    scriptName = os.path.basename(__file__).split('.')[0]
    parser = ZenToolboxUtils.parse_options(scriptVersion, scriptName + scriptSummary + documentationURL)
    # Add in any specific parser arguments for %scriptName
    parser.add_argument("-f", "--fix", action="store_true", default=False,
                        help="attempt to remove any invalid references")
    parser.add_argument("-n", "--cycles", action="store", default="12", type=int,
                        help="maximum times to cycle (with --fix, <= 12)")
    parser.add_argument("-l", "--list", action="store_true", default=False,
                        help="output all supported catalogs")
    parser.add_argument("-c", "--catalog", action="store", default="",
                        help="only scan/fix specified catalog")
    cliOptions = vars(parser.parse_args())
    log, logFileName = ZenToolboxUtils.configure_logging(scriptName, scriptVersion, cliOptions['tmpdir'])
    log.info("Command line options: %s" % (cliOptions))
    if cliOptions['debug']:
        log.setLevel(logging.DEBUG)

    print "\n[%s] Initializing %s v%s (detailed log at %s)" % \
          (time.strftime("%Y-%m-%d %H:%M:%S"), scriptName, scriptVersion, logFileName)

    # Attempt to get the zenoss.toolbox lock before any actions performed
    if not ZenToolboxUtils.get_lock("zenoss.toolbox", log):
        sys.exit(1)

    # Obtain dmd ZenScriptBase connection
    dmd = ZenScriptBase(noopts=True, connect=True).dmd
    log.debug("ZenScriptBase connection obtained")

    anyIssue = False
    global maxCycles
    if cliOptions['fix']:
        if cliOptions['cycles'] > 12:
            maxCycles = 12
        else:
            maxCycles = cliOptions['cycles']
    else:
        maxCycles = 1

    validCatalogList = build_catalog_list(dmd, log)
    if cliOptions['list']:
        print "List of supported Zenoss catalogs to examine:\n"
        for item in validCatalogList:
            print item.prettyName
        log.info("Zencatalogscan finished - list of supported catalogs output to CLI")
    else:
        if cliOptions['catalog']:
            foundItem = False
            for item in validCatalogList:
                if cliOptions['catalog'] == item.prettyName:
                    foundItem = True
                    anyIssue = scan_catalog(item, cliOptions['fix'],
                                            dmd, log, not cliOptions['skipEvents'])
            if not foundItem:
                print("Catalog '%s' unrecognized - unable to scan" % (cliOptions['catalog']))
                log.error("CLI input '%s' doesn't match recognized catalogs" % (cliOptions['catalog']))
                exit(1)
        else:
            for item in validCatalogList:
                anyIssue = scan_catalog(item, cliOptions['fix'],
                                        dmd, log, not cliOptions['skipEvents']) or anyIssue

    # Print final status summary, update log file with termination block
    print("\n[%s] Execution finished in %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"),
                                                 datetime.timedelta(seconds=int(time.time() - executionStart))))
    log.info("zencatalogscan completed in %1.2f seconds" % (time.time() - executionStart))
    log.info("############################################################")

    if not cliOptions['skipEvents']:
        if anyIssue:
            eventSummaryMsg = "%s encountered errors (took %1.2f seconds)" % (scriptName, (time.time() - executionStart))
            eventSeverity = 4
        else:
            eventSummaryMsg = "%s completed without errors (took %1.2f seconds)" % (scriptName, (time.time() - executionStart))
            eventSeverity = 2

        ZenToolboxUtils.send_summary_event(
            eventSummaryMsg, eventSeverity,
            scriptName, "executionStatus",
            documentationURL, dmd
        )

    if anyIssue and not cliOptions['fix']:
        print("** WARNING ** Issues were detected - Consult KB article at")
        print("      https://support.zenoss.com/hc/en-us/articles/203118075\n")
        sys.exit(1)
    else:
        sys.exit(0)
            else:
                eventSummaryMsg = "global_catalog 'paths to uids' - No Errors Detected [--fix was successful] (%d total items)" % \
                                   (catalogObject.initialSize)
        else:
            eventSeverity = 4
            if fix:
                eventSummaryMsg = "global_catalog 'paths to uids' - %d Errors Remain after --fix [consult log file]  (%d total items)" % \
                                   (catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)
            else:
                eventSummaryMsg = "global_catalog 'paths to uids' - %d Errors Detected [run with --fix]  (%d total items)" % \
                                   (catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)

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

    return (catalogObject.runResults[currentCycle]['errorCount'].value() != 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)
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)
            else:
                eventSummaryMsg = "global_catalog 'paths to uids' - No Errors Detected [--fix was successful] (%d total items)" % \
                                   (catalogObject.initialSize)
        else:
            eventSeverity = 4
            if fix:
                eventSummaryMsg = "global_catalog 'paths to uids' - %d Errors Remain after --fix [consult log file]  (%d total items)" % \
                                   (catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)
            else:
                eventSummaryMsg = "global_catalog 'paths to uids' - %d Errors Detected [run with --fix]  (%d total items)" % \
                                   (catalogObject.runResults[currentCycle]['errorCount'].value(), catalogObject.initialSize)

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

    return (catalogObject.runResults[currentCycle]['errorCount'].value() != 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)
Beispiel #7
0
def main():
    """ Scans through zodb hierarchy (from user-supplied path, defaults to /,  checking for PKEs """

    execution_start = time.time()
    scriptName = os.path.basename(__file__).split('.')[0]
    parser = ZenToolboxUtils.parse_options(
        scriptVersion, scriptName + scriptSummary + documentationURL)
    # Add in any specific parser arguments for %scriptName
    parser.add_argument("-f",
                        "--fix",
                        action="store_true",
                        default=False,
                        help="attempt to fix ZenRelationship objects")
    parser.add_argument("-n",
                        "--cycles",
                        action="store",
                        default="2",
                        type=int,
                        help="maximum times to cycle (with --fix)")
    parser.add_argument("-p",
                        "--path",
                        action="store",
                        default="/",
                        type=str,
                        help="base path to scan from (Devices.Server)?")
    parser.add_argument(
        "-u",
        "--unlimitedram",
        action="store_true",
        default=False,
        help="skip transaction.abort() - unbounded RAM, ~40%% faster")
    cli_options = vars(parser.parse_args())
    log, logFileName = ZenToolboxUtils.configure_logging(
        scriptName, scriptVersion, cli_options['tmpdir'])
    log.info("Command line options: %s" % (cli_options))
    if cli_options['debug']:
        log.setLevel(logging.DEBUG)

    print "\n[%s] Initializing %s v%s (detailed log at %s)" % \
          (time.strftime("%Y-%m-%d %H:%M:%S"), scriptName, scriptVersion, logFileName)

    # Attempt to get the zenoss.toolbox lock before any actions performed
    if not ZenToolboxUtils.get_lock("zenoss.toolbox", log):
        sys.exit(1)

    # Obtain dmd ZenScriptBase connection
    dmd = ZenScriptBase(noopts=True, connect=True).dmd
    log.debug("ZenScriptBase connection obtained")

    counters = {
        'item_count': ZenToolboxUtils.Counter(0),
        'error_count': ZenToolboxUtils.Counter(0),
        'repair_count': ZenToolboxUtils.Counter(0)
    }

    processed_path = re.split("[./]", cli_options['path'])
    if processed_path[0] == "app":
        processed_path = processed_path[1:]
    processed_path = '/'.join(processed_path) if processed_path else '/'

    try:
        folder = dmd.getObjByPath(processed_path)
    except KeyError:
        print "Invalid path: %s" % (cli_options['path'])
    else:
        print("[%s] Examining items under the '%s' path (%s):" % (strftime(
            "%Y-%m-%d %H:%M:%S", localtime()), cli_options['path'], folder))
        log.info("Examining items under the '%s' path (%s)",
                 cli_options['path'], folder)
        findPOSKeyErrors(folder, cli_options['fix'],
                         cli_options['unlimitedram'], dmd, log, counters,
                         cli_options['cycles'])
        print

    print("\n[%s] Execution finished in %s\n" %
          (strftime("%Y-%m-%d %H:%M:%S", localtime()),
           datetime.timedelta(seconds=int(time.time() - execution_start))))
    log.info("findposkeyerror completed in %1.2f seconds",
             time.time() - execution_start)
    log.info("############################################################")

    if not cli_options['skipEvents']:
        if counters['error_count'].value():
            eventSeverity = 4
            eventSummaryMsg = "%s encountered %d errors (took %1.2f seconds)" % \
                               (scriptName, counters['error_count'].value(), (time.time() - execution_start))
        else:
            eventSeverity = 2
            eventSummaryMsg = "%s completed without errors (took %1.2f seconds)" % \
                               (scriptName, (time.time() - execution_start))

        ZenToolboxUtils.send_summary_event(eventSummaryMsg, eventSeverity,
                                           scriptName, "executionStatus",
                                           documentationURL, dmd)

    if ((counters['error_count'].value() > 0) and not cli_options['fix']):
        print("** WARNING ** Issues were detected - Consult KB article at")
        print("      https://support.zenoss.com/hc/en-us/articles/203117795\n")
        sys.exit(1)
    else:
        sys.exit(0)
Beispiel #8
0
def main():
    '''Scans zodb objects for ZenRelations issues.  If --fix, attempts repair.'''

    execution_start = time.time()
    scriptName = os.path.basename(__file__).split('.')[0]
    parser = ZenToolboxUtils.parse_options(scriptVersion, scriptName + scriptSummary + documentationURL)
    # Add in any specific parser arguments for %scriptName
    parser.add_argument("-f", "--fix", action="store_true", default=False,
                        help="attempt to remove any invalid references")
    parser.add_argument("-n", "--cycles", action="store", default="2", type=int,
                        help="maximum times to cycle (with --fix)")
    parser.add_argument("-u", "--unlimitedram", action="store_true", default=False,
                        help="skip transaction.abort() - unbounded RAM, ~40%% faster")
    cli_options = vars(parser.parse_args())
    log, logFileName = ZenToolboxUtils.configure_logging(scriptName, scriptVersion, cli_options['tmpdir'])
    log.info("Command line options: %s" % (cli_options))
    if cli_options['debug']:
        log.setLevel(logging.DEBUG)

    print "\n[%s] Initializing %s v%s (detailed log at %s)" % \
          (time.strftime("%Y-%m-%d %H:%M:%S"), scriptName, scriptVersion, logFileName)

    # Attempt to get the zenoss.toolbox lock before any actions performed
    if not ZenToolboxUtils.get_lock("zenoss.toolbox", log):
        sys.exit(1)

    # Obtain dmd ZenScriptBase connection
    dmd = ZenScriptBase(noopts=True, connect=True).dmd
    log.debug("ZenScriptBase connection obtained")

    counters = {
        'item_count': ZenToolboxUtils.Counter(0),
        'error_count': ZenToolboxUtils.Counter(0),
        'repair_count': ZenToolboxUtils.Counter(0)
        }

    scan_relationships(cli_options['fix'], cli_options['cycles'], cli_options['unlimitedram'], dmd, log, counters)

    if not cli_options['skipEvents']:
        if counters['error_count'].value():
            eventSeverity = 4
            eventSummaryMsg = "%s encountered %d errors (took %1.2f seconds)" % \
                               (scriptName, counters['error_count'].value(), (time.time() - execution_start))
        else:
            eventSeverity = 2
            eventSummaryMsg = "%s completed without errors (took %1.2f seconds)" % \
                               (scriptName, (time.time() - execution_start))

        ZenToolboxUtils.send_summary_event(
            eventSummaryMsg, eventSeverity,
            scriptName, "executionStatus",
            documentationURL, dmd
        )

    # Print final status summary, update log file with termination block
    log.info("zenrelationscan examined %d objects, encountered %d errors, and attempted %d repairs",
             counters['item_count'].value(), counters['error_count'].value(), counters['repair_count'].value())
    print("\n[%s] Execution finished in %s\n" % (strftime("%Y-%m-%d %H:%M:%S", localtime()),
           datetime.timedelta(seconds=int(time.time() - execution_start))))
    log.info("zenrelationscan completed in %1.2f seconds" % (time.time() - execution_start))
    log.info("############################################################")

    if ((counters['error_count'].value() > 0) and not cli_options['fix']):
        print("** WARNING ** Issues were detected - Consult KB article at")
        print("      https://support.zenoss.com/hc/en-us/articles/203121165\n")
        sys.exit(1)
    else:
        sys.exit(0)
def main():
    """ Scans through zodb hierarchy (from user-supplied path, defaults to /,  checking for PKEs """

    execution_start = time.time()
    scriptName = os.path.basename(__file__).split('.')[0]
    parser = ZenToolboxUtils.parse_options(scriptVersion, scriptName + scriptSummary + documentationURL)
    # Add in any specific parser arguments for %scriptName
    parser.add_argument("-f", "--fix", action="store_true", default=False,
                        help="attempt to fix ZenRelationship objects")
    parser.add_argument("-n", "--cycles", action="store", default="2", type=int,
                        help="maximum times to cycle (with --fix)")
    parser.add_argument("-p", "--path", action="store", default="/", type=str,
                        help="base path to scan from (Devices.Server)?")
    parser.add_argument("-u", "--unlimitedram", action="store_true", default=False,
                        help="skip transaction.abort() - unbounded RAM, ~40%% faster")
    cli_options = vars(parser.parse_args())
    log, logFileName = ZenToolboxUtils.configure_logging(scriptName, scriptVersion, cli_options['tmpdir'])
    log.info("Command line options: %s" % (cli_options))
    if cli_options['debug']:
        log.setLevel(logging.DEBUG)

    print "\n[%s] Initializing %s v%s (detailed log at %s)" % \
          (time.strftime("%Y-%m-%d %H:%M:%S"), scriptName, scriptVersion, logFileName)

    # Attempt to get the zenoss.toolbox lock before any actions performed
    if not ZenToolboxUtils.get_lock("zenoss.toolbox", log):
        sys.exit(1)

    # Obtain dmd ZenScriptBase connection
    dmd = ZenScriptBase(noopts=True, connect=True).dmd
    log.debug("ZenScriptBase connection obtained")

    counters = {
        'item_count': ZenToolboxUtils.Counter(0),
        'error_count': ZenToolboxUtils.Counter(0),
        'repair_count': ZenToolboxUtils.Counter(0)
        }

    processed_path = re.split("[./]", cli_options['path'])
    if processed_path[0] == "app":
        processed_path = processed_path[1:]
    processed_path = '/'.join(processed_path) if processed_path else '/'

    try:
        folder = dmd.getObjByPath(processed_path)
    except KeyError:
        print "Invalid path: %s" % (cli_options['path'])
    else:
        print("[%s] Examining items under the '%s' path (%s):" %
              (strftime("%Y-%m-%d %H:%M:%S", localtime()), cli_options['path'], folder))
        log.info("Examining items under the '%s' path (%s)", cli_options['path'], folder)
        findPOSKeyErrors(folder, cli_options['fix'], cli_options['unlimitedram'], dmd, log, counters, cli_options['cycles'])
        print

    print("\n[%s] Execution finished in %s\n" %
          (strftime("%Y-%m-%d %H:%M:%S", localtime()),
           datetime.timedelta(seconds=int(time.time() - execution_start))))
    log.info("findposkeyerror completed in %1.2f seconds", time.time() - execution_start)
    log.info("############################################################")

    if not cli_options['skipEvents']:
        if counters['error_count'].value():
            eventSeverity = 4
            eventSummaryMsg = "%s encountered %d errors (took %1.2f seconds)" % \
                               (scriptName, counters['error_count'].value(), (time.time() - execution_start))
        else:
            eventSeverity = 2
            eventSummaryMsg = "%s completed without errors (took %1.2f seconds)" % \
                               (scriptName, (time.time() - execution_start))

        ZenToolboxUtils.send_summary_event(
            eventSummaryMsg, eventSeverity,
            scriptName, "executionStatus",
            documentationURL, dmd
        )

    if ((counters['error_count'].value() > 0) and not cli_options['fix']):
        print("** WARNING ** Issues were detected - Consult KB article at")
        print("      https://support.zenoss.com/hc/en-us/articles/203117795\n")
        sys.exit(1)
    else:
        sys.exit(0)