def go(driver): from Products.ZenUtils.ZenScriptBase import ZenScriptBase from ZenPacks.zenoss.ZenMailTx.MailTxConfigService import MailTxConfigService zendmd = ZenScriptBase(noopts=True, connect=True) dmd = zendmd.dmd d = dmd.Devices.findDevice(device) if not d: sys.stderr.write("Unable to find device %s\n" % device) sys.exit(1) log.setLevel(logging.DEBUG) service = MailTxConfigService(dmd, d.perfServer().id) if not service: sys.stderr.write("Unable to find configuration for %s" % device) proxy = service.remote_getDeviceConfigs([device]) if proxy: proxy = proxy[0] else: raise ValueError( "Unable to find a valid MailTx config for device %s" % device) config = proxy.datasources if datasource: config = [c for c in proxy.datasources if c.name == datasource] if not config: raise ValueError( "Unable to find a MailTx config %s for device %s" % (datasource or '', device)) config = config[0] config.ignoreIds = set() now = time.time() yield sendMessage(config) log.debug("Result of message send: %s", driver.next()) yield getMessage(config, 5.0) log.debug("Result of message fetch: %s", driver.next()) log.info("Message delivered in %.2f seconds" % (time.time() - now))
def getmysqlcreds(): """Fetch the mysql creds from the object database and store them in the global file for use in later commands. returns True on success, False on failure """ pids = os.popen('pgrep -f zeo.py').read().split('\n') pids = [int(p) for p in pids if p] if len(pids) < 1: log.warning('zeo is not running') return False log.debug("Fetching mysql credentials") print "Fetching mysql credentials" mysqlpass = '******' mysqluser = '******' mysqlport = '3306' mysqlhost = 'localhost' sys.path.insert(0, os.path.join(zenhome, 'lib/python')) try: import Globals from Products.ZenUtils.ZenScriptBase import ZenScriptBase zsb = ZenScriptBase(noopts=True, connect=True) zsb.getDataRoot() dmd = zsb.dmd mysqlpass = dmd.ZenEventManager.password mysqluser = dmd.ZenEventManager.username mysqlport = dmd.ZenEventManager.port mysqlhost = dmd.ZenEventManager.host except Exception, ex: log.exception("Unable to open the object database for " "mysql credentials") pass
def get_device_properties(slots): """Retrieve device attributes from Zenoss and store in local data structure (slots). """ dmd = ZenScriptBase(connect=True).dmd for device in dmd.Devices.getSubDevices(): groups = device.getDeviceGroupNames() for a in range(0, len(groups)): if groups[a].find(groupName) != -1: slot = device.rackSlot slotWords = (str(slot)).split() slotNum = int(slotWords[len(slotWords) - 1]) serialNum = device.getHWSerialNumber() name = device.getDeviceName() ip = device.getManageIp() classPath = device.getDeviceClassPath() classPath.strip() classes = classPath.split('/') className = classes[len(classes) - 1] # NOTE: Temporary hack to accommodate 1900 if slotNum == 1: if name.find("ZX1900BaseDevice") != -1: slotNum = 2 # Store info in slots slotInfo = slots[slotNum] slotInfo['ip'] = ip slotInfo['name'] = name slotInfo['serial'] = serialNum slotInfo['class'] = className
def main(): """Scans catalogs, reindexes if needed, and prints a summary""" cmdLineOptions = parse_options() dmd = ZenScriptBase(noopts=True, connect=True).dmd catalogList = [ dmd.global_catalog, dmd.Networks.ipSearch, dmd.IPv6Networks.ipSearch, dmd.Devices.deviceSearch, dmd.Services.serviceSearch, dmd.ZenLinkManager.layer2_catalog, dmd.ZenLinkManager.layer3_catalog, dmd.maintenanceWindowSearch, dmd.zenPackPersistence, dmd.Manufacturers.productSearch ] for catalog in catalogList: scan_catalog(catalog, cmdLineOptions['fix']) if cmdLineOptions['fix']: print "" print "Reindexing dmd Objects..." try: dmd.Devices.reIndex() dmd.Events.reIndex() dmd.Manufacturers.reIndex() dmd.Networks.reIndex() except Exception, e: summaryMsg.append("") summaryMsg.append(" ** Exception encountered when reindexing dmd object %s" % (e))
def set_device_properties(slots): """Use local data structure (slots) to set device attributes in Zenoss. """ # Set serial number, slot & name. # Zenoss will overwrite serial number & slot for Znyx devices. # So, only set these values for ZXSBC devices. # NOTE: Add error handling & logging. dmd = ZenScriptBase(connect=True).dmd for device in dmd.Devices.getSubDevices(): for slotNum in range(0, len(slots)): slotInfo = slots[slotNum] # Skip empty slots if slotInfo['serial'] == None: continue if slotInfo['ip'] == device.getManageIp(): #if device.id != device.getDeviceName(): device.renameDevice(slotInfo['name']) manf = device.getOSManufacturerName() if not manf.find("Znyx") != -1: device.setHWSerialNumber(slotInfo['serial']) device.rackSlot = slotNum dmd.Devices.reIndex() commit()
def main(): '''Performs reindex call on different DMD categories (used to be a part of zencatalogscan)''' execution_start = time.time() cli_options = parse_options() log = configure_logging('zenindextool') log.info("Command line options: %s" % (cli_options)) if cli_options['debug']: log.setLevel(logging.DEBUG) # Attempt to get the zenoss.toolbox lock before any actions performed if not get_lock("zenoss.toolbox", log): sys.exit(1) # Obtain dmd ZenScriptBase connection dmd = ZenScriptBase(noopts=True, connect=True).dmd log.debug("ZenScriptBase connection obtained") any_issue = False # Else build list of catalogs, then process catalog(s) and perform reindex if --fix types_to_reIndex = { 'Devices': 'dmd.Devices', 'Events': 'dmd.Events', 'Manufacturers': 'dmd.Manufacturers', 'Networks': 'dmd.Networks', 'Services': 'dmd.Services' } if cli_options['list'] or not cli_options['type']: # Output list of present catalogs to the UI, perform no further operations print "List of dmd types that support reIndex() calls from this script:\n" print "\n".join(types_to_reIndex.keys()) log.info( "Zenreindextool finished - list of supported types output to CLI") else: if cli_options['type'] in types_to_reIndex.keys(): any_issue = reindex_dmd_objects( cli_options['type'], types_to_reIndex[cli_options['type']], dmd, log) # exit with error if there are any issues if any_issue == False: exit(1) else: print("Type '%s' unrecognized - unable to reIndex()" % (cli_options['type'])) log.error("CLI input '%s' doesn't match recognized types" % (cli_options['type'])) exit(1) # 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() - execution_start)))) log.info("zenindextool completed in %1.2f seconds" % (time.time() - execution_start)) log.info("############################################################")
def main(): """ Scans through zodb hierarchy (from user-supplied path, defaults to /, checking for PKEs """ execution_start = time.time() cli_options = parse_options() log = configure_logging('findposkeyerror') log.info("Command line options: %s" % (cli_options)) if cli_options['debug']: log.setLevel(logging.DEBUG) # Attempt to get the zenoss.toolbox lock before any actions performed if not 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': Counter(0), 'error_count': Counter(0), 'repair_count': 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):\n" % (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) 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 ((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)
def eventStats(): try: import Globals from Products.ZenUtils.ZenScriptBase import ZenScriptBase from Products.Zuul import getFacade zsb = ZenScriptBase(noopts=True, connect=True) zsb.getDataRoot() zepfacade = getFacade('zep') statsList = zepfacade.getStats() return '\n\n'.join([str(item) for item in statsList]) except Exception, ex: log = logging.getLogger('zendiag') log.exception(ex)
def validate(self, argz): dmd = ZenScriptBase(noopts=True, connect=True).dmd impactPack = dmd.ZenPackManager.packs.findObjectsById( 'ZenPacks.zenoss.Impact') if not impactPack: log.info('The Impact ZenPack is not installed') return impactPack = impactPack[0] if cmp(parse_version(impactPack.version), parse_version(MIN_ZP_VERS)) > 0: log.info('Impact ZenPack version %s is installed, OK to migrate', impactPack.version) return log.error('ZenPacks.zenoss.Impact is at version %s, but must be ' \ 'at least version %s, exiting', impactPack.version, MIN_ZP_VERS) raise ValidationException()
def main(): parser = argparse.ArgumentParser(description="Find POSKeyErrors 1.4") parser.add_argument( "folder", metavar="PATH", type=str, help="Object path where to start searching from. E.g. Devices.Server") parser.add_argument("--fixrels", action="store_true", default=False, help="Automatically fix ZenRelationship objects") args = parser.parse_args() #import pdb; pdb.set_trace() # Configure NullHandler for logging to suppress 'no handler for # logger' messages. logger = logging.getLogger() logger.addHandler(logging.NullHandler()) ZenScriptBase.doesLogging = False # disable logging configuration dmd = ZenScriptBase(noopts=True, connect=True).dmd # Split along '/' and '.' delimiters path = re.split("[./]", args.folder) # If the first path element is 'app' (name of root node in zendmd), # then remove it from the path, because that name doesn't actually # exist in the database. if path[0] == "app": path = path[1:] # Rebuild path using '/' delimiter path = '/'.join(path) if path else '/' try: folder = dmd.getObjByPath(path) except KeyError: print "Invalid path: %s" % (args.folder, ) else: for exname, ex, objType, objId, parentPath in findPOSKeyErrors(folder): print "%s: %s on %s '%s' of %s" \ % (exname, ex, objType, objId, _getPathStr(parentPath)) # example == POSKeyError: 0x0118ef28 on relationship 'dependents' of app.zport.dmd.Devices.VMware.TNL1DMZVC01.Hosts.devices.TNL1DMZVC01_host-125.hw if args.fixrels: if isinstance(ex, POSKeyError): fixPOSKeyError(exname, ex, objType, objId, parentPath)
def main(): '''Scans zodb objects for ZenRelations issues. If --fix, attempts repair.''' execution_start = time.time() cli_options = parse_options() log = configure_logging('zenrelationscan') log.info("Command line options: %s" % (cli_options)) if cli_options['debug']: log.setLevel(logging.DEBUG) counters = { 'item_count': Counter(0), 'error_count': Counter(0), 'repair_count': Counter(0) } # Attempt to get the zenoss.toolbox lock before any actions performed if not get_lock("zenoss.toolbox", log): sys.exit(1) # Obtain dmd ZenScriptBase connection dmd = ZenScriptBase(noopts=True, connect=True).dmd log.debug("ZenScriptBase connection obtained") scan_relationships(cli_options['fix'], cli_options['cycles'], cli_options['unlimitedram'], dmd, log, counters) # Print final status summary, update log file with termination block 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 get_device_properties(): """Retrieve device attributes from Zenoss and store in local data structure (slots). """ dmd = ZenScriptBase(connect=True).dmd #Retrieve device attributes from Zenoss and store in local data structure (slots). print("get_device_properties") global slots global groupName for device in dmd.Devices.getSubDevices(): groups = device.getDeviceGroupNames() for a in range (0,len(groups)): if groups[a].find(groupName) != -1: # NOTE: ZNYX BOARDS DON'T HAVE CORRECT SLOT NUMBER #slot = device.rackSlot #slotWords = (str(slot)).split() #slotNum = int(slotWords[len(slotWords)-1]) serialNum = device.getHWSerialNumber() if serialNum == None: serialNum = "" ip = device.getManageIp() name = device.getDeviceName() classPath = device.getDeviceClassPath() classPath.strip() classes = classPath.split('/') className = classes[len(classes)-1] # Find the right slot. for slotNum in range (0,len(slots)): if slots[slotNum]['ip'] == ip: # Store info in slots slotInfo = slots[slotNum] slotInfo['zname'] = name slotInfo['class'] = className slotInfo['serial'] = serialNum break
def main(): scriptSummary = "Export event from redis or send exported to Zenoss" scriptName = os.path.basename(__file__).split('.')[0] scriptVersion = '1.0.0' parser = ZenToolboxUtils.parse_options( scriptVersion, "%s: %s" % (scriptName, scriptSummary)) parser.add_argument('-e', '--export', action='store', metavar='FILENAME', help='Export events from redis') parser.add_argument('-p', '--pretty', action='store_true', default=False, help='Export events in a pretty format') parser.add_argument('-l', '--load', action='store', metavar='FILENAME', help='Send events from file into Zenoss') cli_options = vars(parser.parse_args()) dmd = ZenScriptBase(noopts=True, connect=True).dmd r = redis.StrictRedis( dmd.getProperty('eventReplayRedisServer'), dmd.getProperty('eventReplayRedisPort'), db=dmd.getProperty('eventReplayRedisDB'), ) if cli_options['export']: exportEvents(r, cli_options['export'], cli_options['pretty']) sys.exit() elif cli_options['load'] and os.path.isfile(cli_options['load']): importEvents(dmd, cli_options['load'])
def processResults(self, cmd, result): """ Process the results for command "lsdrive -delim :". """ update = False datapointMap = dict([(dp.id, dp) for dp in cmd.points]) devname = cmd.deviceConfig.device # returned from datasource component field with ${here/id} componentid = cmd.component rresult = Utils.cmdParser(cmd.result.output, 'id', 'DRIVE_ID') # specific component device rresult = rresult[componentid] # drive status raise event if rresult['status'] != 'online': result.events.append( Utils.getEvent(cmd, "Drive status not online", clear=False)) update = True # drive error sequence number if rresult['error_sequence_number'] != '': result.events.append( Utils.getEvent(cmd, "Drive error sequence number: " + rresult['error_sequence_number'], clear=False)) update = True # update current component if needed if update: scriptbase = ZenScriptBase(noopts=1, connect=True) device = scriptbase.findDevice(devname) component = device.drives.findObjectsById(componentid)[0] component.drive_status = rresult['status'] component.error_sequence_number = rresult['error_sequence_number'] commit()
def __init__(self, error_queue, idx, worker_count, parent_queue, counter, semaphore, cond, cancel, terminator, fields=None, logtoggle=None): super(ReindexProcess, self).__init__() self.error_queue = error_queue self.idx = idx self.worker_count = worker_count self.parent_queue = parent_queue self.counter = counter self.semaphore = semaphore self.cond = cond self.cancel = cancel self.terminator = terminator self.fields = fields self.logtoggle = logtoggle self.semaphore_acquired = False self._batch = [] zsb = ZenScriptBase(connect=True, should_log=False) self.dmd = zsb.dmd self._db = zsb.db self.index_client = zope.component.createObject( 'ModelIndex', get_solr_config())
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(): '''Checks for old/unused ip addresses. If --fix, attempts to remove old unused ip addresses. Builds list of available non-empty catalogs.''' 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 stale references") parser.add_argument("-n", "--cycles", action="store", default="12", type=int, help="maximum times to cycle (with --fix)") 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") 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") any_issue = [False, 0] unrecognized_catalog = False # Build list of catalogs, then process catalog(s) and perform reindex if --fix present_catalog_dict = build_catalog_dict(dmd, log) if cli_options['list']: # Output list of present catalogs to the UI, perform no further operations print "List of supported Zenoss catalogs to examine:\n" print "\n".join(present_catalog_dict.keys()) log.info( "zennetworkclean finished - list of supported catalogs output to CLI" ) else: # Scan through catalog(s) depending on --catalog parameter if cli_options['catalog']: if cli_options['catalog'] in present_catalog_dict.keys(): # Catalog provided as parameter is present - scan just that catalog any_issue = scan_catalog( cli_options['catalog'], present_catalog_dict[cli_options['catalog']], cli_options['fix'], cli_options['cycles'], dmd, log) else: unrecognized_catalog = True print("Catalog '%s' unrecognized - unable to scan" % (cli_options['catalog'])) log.error("CLI input '%s' doesn't match recognized catalogs" % (cli_options['catalog'])) else: # Else scan for all catalogs in present_catalog_dict for catalog in present_catalog_dict.keys(): any_issue = scan_catalog( catalog, present_catalog_dict[catalog], cli_options['fix'], cli_options['cycles'], dmd, log) or any_issue # 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() - execution_start)))) log.info("zennetworkclean completed in %1.2f seconds" % (time.time() - execution_start)) log.info("############################################################") if any_issue and not cli_options['fix']: sys.exit(1) else: sys.exit(0)
def main(): '''Performs reindex call on different DMD categories (used to be a part of zencatalogscan)''' 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("-l", "--list", action="store_true", default=False, help="output all supported reIndex() types") parser.add_argument("-t", "--type", action="store", default="", help="specify which type to reIndex()") 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") any_issue = False # Else build list of catalogs, then process catalog(s) and perform reindex if --fix types_to_reIndex = { 'Devices': 'dmd.Devices', 'Events': 'dmd.Events', 'Manufacturers': 'dmd.Manufacturers', 'Networks': 'dmd.Networks', 'Services': 'dmd.Services', } if not USE_MODEL_CATALOG: types_to_reIndex['DeviceSearch'] = ' dmd.Devices.deviceSearch' if cli_options['list'] or not cli_options['type']: # Output list of present catalogs to the UI, perform no further operations print "List of dmd types that support reIndex() calls from this script:\n" print "\n".join(types_to_reIndex.keys()) log.info( "Zenreindextool finished - list of supported types output to CLI") exit(1) if cli_options['type'] in types_to_reIndex.keys(): any_issue = reindex_dmd_objects(cli_options['type'], types_to_reIndex[cli_options['type']], dmd, log) else: print("Type '%s' unrecognized - unable to reIndex()" % (cli_options['type'])) log.error("CLI input '%s' doesn't match recognized types" % (cli_options['type'])) exit(1) # 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() - execution_start)))) log.info("zenindextool completed in %1.2f seconds" % (time.time() - execution_start)) log.info("############################################################") if any_issue: print("** WARNING ** Issues were encountered - Consult KB article at") print(" https://support.zenoss.com/hc/en-us/articles/203263689\n") sys.exit(1) sys.exit(0)
def zenossInfo(): "get the About:Versions page data" def format_data(fmt, data): return [fmt % datum for datum in data] + [''] try: print "Gathering info from zodb..." import Globals from Products.ZenUtils.ZenScriptBase import ZenScriptBase from Products.Zuul import getFacade zsb = ZenScriptBase(noopts=True, connect=True) zsb.getDataRoot() header_data = [('Report Data', datetime.datetime.now()), ('Server Key', zsb.dmd.uuid), ('Google Key', zsb.dmd.geomapapikey)] counter = {} decomm = 0 for d in zsb.dmd.Devices.getSubDevices(): if d.productionState < 0: decomm += 1 else: index = '%s %s' % \ (d.getDeviceClassPath(), d.getProductionStateString()) count = counter.get(index, 0) counter[index] = count + 1 totaldev = zsb.dmd.Devices.countDevices() device_summary_header_data = [ ('Total Devices', totaldev), ('Total Decommissioned Devices', decomm), ('Total Monitored Devices', totaldev - decomm), ] device_summary_header = ['Device Breakdown by Class and State:'] counter_keylist = counter.keys() counter_keylist.sort() device_summary_data = [(k, counter[k]) for k in counter_keylist] zenpacks_header = ['ZenPacks:'] zenpack_ids = zsb.dmd.ZenPackManager.packs.objectIds() zenoss_versions_data = [(record['header'], record['data']) for record in zsb.dmd.About.getAllVersions()] uuid_data = [('uuid', zsb.dmd.uuid)] event_start = time.time() - 24 * 60 * 60 product_count = 0 for name in zsb.dmd.Manufacturers.getManufacturerNames(): for product_name in zsb.dmd.Manufacturers.getProductNames(name): product_count = product_count + 1 # Hub collector Data collector_header = ['Hub and Collector Information'] hub_data = [] remote_count = 0 local_count = 0 for hub in zsb.dmd.Monitors.Hub.getHubs(): hub_data.append("Hub: %s" % hub.id) for collector in hub.collectors(): hub_data.append("\tCollector: %s IsLocal(): %s" % (collector.id, collector.isLocalHost())) if not collector.isLocalHost(): hub_data.append("\tCollector(Remote): %s" % collector.id) remote_count = remote_count + 1 else: hub_data.append("\tCollector(Local): %s " % collector.id) local_count = local_count + 1 zep = getFacade('zep') tail_data = [ ('Evt Rules', zsb.dmd.Events.countInstances()), ('Evt Count (Last 24 Hours)', zep.countEventsSince(event_start)), ('Reports', zsb.dmd.Reports.countReports()), ('Templates', zsb.dmd.Devices.rrdTemplates.countObjects()), ('Systems', zsb.dmd.Systems.countChildren()), ('Groups', zsb.dmd.Groups.countChildren()), ('Locations', zsb.dmd.Locations.countChildren()), ('Users', len(zsb.dmd.ZenUsers.getUsers())), ('Product Count', product_count), ('Local Collector Count', local_count), ('Remote Collector Count', remote_count) ] detail_prefix = ' ' std_key_data_fmt = '%s: %s' detail_std_key_data_fmt = detail_prefix + std_key_data_fmt detail_data_fmt = detail_prefix + '%s' center_justify_fmt = '%10s: %s' return_data = ( format_data(std_key_data_fmt, header_data) + format_data(std_key_data_fmt, device_summary_header_data) + device_summary_header + format_data(detail_std_key_data_fmt, device_summary_data) + zenpacks_header + format_data(detail_data_fmt, zenpack_ids) + format_data(center_justify_fmt, zenoss_versions_data + uuid_data) + collector_header + format_data('%s', hub_data) + format_data(std_key_data_fmt, tail_data)) return '\n'.join(return_data) except Exception, ex: log.exception(ex)
def _get_zodb_connection(self): print("Connecting to zodb...") from Products.ZenUtils.ZenScriptBase import ZenScriptBase self.dmd = ZenScriptBase(connect=True).dmd
p.set_defaults(cust_name="Enterprise Customer") # Title - example "Internal IT Infrastructure" p.add_option("-t", "--title", action="store", dest="title_text") p.set_defaults(title_text="Architecture Review") opts, args = p.parse_args() outfile = opts.outfile cust_name = opts.cust_name title_text = opts.title_text args = None # Open file to write results out = open(outfile + ".txt", "w") jsonout = open(outfile + ".json", "w") # Connect to DMD print "Trying to connect to DMD" zenscript = ZenScriptBase(connect=True, noopts=1) dmd = None try: dmd = zenscript.dmd print "Connected to DMD. Zenoss version found: %s" % dmd.version except Exception, e: print "Connection to zenoss dmd failed: %s\n" % e sys.exit(1) def _discoverLocalhostNames(): names = set() # check the many variants of hostname for args in ("", "-i", "-I", "-a", "-A", "-s"): cmd = "hostname %s" % args p = subprocess.Popen(cmd,
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)
def process_config_changes(slots): """Determine if chassis or Zenoss configuration has changed and process any changes. """ # CHASSIS CHANGES newSlots = [None] * maxSlots slotStatus = [None] * maxSlots # Initialize IP addresses in new table. for slotNum in range(0, len(slots)): newSlots[slotNum] = {'ip': slots[slotNum]['ip']} # Derive the device class from the device itself. Then get the latest serial number and # mState from the shelf manager. # NOTE: Order is important. Call setup_chassis before get_device_names. setup_chassis(newSlots) get_device_names(newSlots, False) for slotNum in range(1, len(newSlots)): newSlotInfo = newSlots[slotNum] slotInfo = slots[slotNum] # Error condition. Neither of these will be empty. if newSlotInfo == None or slotInfo == None: # NOTE: Generate event continue # Retrieve serial number and mState. newSerial = newSlotInfo['serial'] newMState = int(newSlotInfo['mState']) newClass = newSlotInfo['class'] oldSerial = slotInfo['serial'] oldMState = int(slotInfo['mState']) oldClass = slotInfo['class'] if newMState == 0: if oldMState == 0 or oldClass == None or oldSerial == None: # No Change -- slot still empty. slotStatus[slotNum] = boardUnchanged else: # Board Removed. slotStatus[slotNum] = boardRemoved else: if ((oldMState == 0) or (oldClass == None) or (oldSerial == None)): # Board Added slotStatus[slotNum] = boardAdded elif (newSerial != oldSerial) or (newClass != oldClass): # Hot Swap slotStatus[slotNum] = boardHotSwap else: # No Change slotStatus[slotNum] = boardUnchanged # ZENOSS CHANGES # Setup dmd object dmd = ZenScriptBase(connect=True).dmd for device in dmd.Devices.getSubDevices(): groups = device.getDeviceGroupNames() for a in range(0, len(groups)): if groups[a].find(groupName) != -1: slot = device.rackSlot slotWords = (str(slot)).split() slotNum = int(slotWords[len(slotWords) - 1]) serialNum = device.getHWSerialNumber() name = device.getDeviceName() ip = device.getManageIp() classPath = device.getDeviceClassPath() classPath.strip() classes = classPath.split('/') className = classes[len(classes) - 1] # User could have changed slot, serial, ip, name or class. # Zenoss modeling will reset slot & serial, so don't worry about these. # User not allowed to change IP address in first release. Log error. # NOTE: Log error here & generate event. Test changing IP later. # User not allowed to change class. # NOTE: Log error here & generate event. # User can change name...This is OK. Just update internal tables. newSlots[slotNum]['name'] = name slots[slotNum]['name'] = name for slotNum in range(1, len(newSlots)): status = slotStatus[slotNum] if status == None or status == boardUnchanged: continue if status == boardRemoved: device = dmd.Devices.findDevice( slots[slotNum]['name']) # Delete device. device.deleteDevice() commit() else: newSlotInfo = newSlots[slotNum] newIp = newSlotInfo['ip'] newName = newSlotInfo['name'] newClass = newSlotInfo['class'] newSerial = newSlotInfo['serial'] if (newClass == "ShelfMgr") or (newClass == "ZXSBC"): prefix = "/Network/" else: prefix = "/Network/OASwitch/" newPath = prefix + newClass if (status == boardAdded): # Add new device via Zenoss. add_dmd_device(newIp, newName, newPath, groupName, slotNum, newSerial) else: # Hot Swap # If different class, then delete old device and add new one. # Otherwise, generate event. if (newClass != slots[slotNum]['class']): device = dmd.Devices.findDevice(slots[slotNum]['name']) device.deleteDevice() commit() add_dmd_device(newIp, newName, newPath, groupName, slotNum, newSerial) else: # NOTE: Add event here. print 'swapped boards of type %s' % newClass dmd.Devices.reIndex() commit()
def main(): '''Scans catalogs for broken references. If --fix, attempts to remove broken references. Builds list of available non-empty catalogs. If --reindex, attempts dmd.reIndex().''' execution_start = time.time() cli_options = parse_options() log = configure_logging('zencatalogscan') log.info("Command line options: %s" % (cli_options)) if cli_options['debug']: log.setLevel(logging.DEBUG) # Attempt to get the zenoss.toolbox lock before any actions performed if not get_lock("zenoss.toolbox", log): sys.exit(1) # Obtain dmd ZenScriptBase connection dmd = ZenScriptBase(noopts=True, connect=True).dmd log.debug("ZenScriptBase connection obtained") any_issue = False unrecognized_catalog = False # Build list of catalogs, then process catalog(s) and perform reindex if --fix present_catalog_dict = build_catalog_dict(dmd, log) if cli_options['list']: # Output list of present catalogs to the UI, perform no further operations print "List of supported Zenoss catalogs to examine:\n" print "\n".join(present_catalog_dict.keys()) log.info( "Zencatalogscan finished - list of supported catalogs output to CLI" ) else: # Scan through catalog(s) depending on --catalog parameter if cli_options['catalog']: if cli_options['catalog'] in present_catalog_dict.keys(): # Catalog provided as parameter is present - scan just that catalog any_issue = scan_catalog( cli_options['catalog'], present_catalog_dict[cli_options['catalog']], cli_options['fix'], cli_options['cycles'], dmd, log) else: unrecognized_catalog = True print("Catalog '%s' unrecognized - unable to scan" % (cli_options['catalog'])) log.error("CLI input '%s' doesn't match recognized catalogs" % (cli_options['catalog'])) else: # Else scan for all catalogs in present_catalog_dict for catalog in present_catalog_dict.keys(): any_issue = scan_catalog( catalog, present_catalog_dict[catalog], cli_options['fix'], cli_options['cycles'], dmd, log) or any_issue # 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() - execution_start)))) log.info("zencatalogscan completed in %1.2f seconds" % (time.time() - execution_start)) log.info("############################################################") if any_issue and not cli_options['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)
parser = OptionParser() parser.add_option("-f", "--file", dest="outputFile", help="Please specify full path to output file", metavar="FILE") (options, args) = parser.parse_args() if not options.outputFile: parser.print_help() sys.exit() of = open(options.outputFile, "w") localtime = time.asctime( time.localtime(time.time()) ) of.write(localtime + "\n\n") # Need noopts=True or it barfs with the script options dmd = ZenScriptBase(connect=True, noopts=True).dmd deviceList=[] for dev in dmd.Devices.getSubDevices(): deviceList.append(dev.id) #Sort the device on id deviceList.sort() for dev in deviceList: d = dmd.Devices.findDevice(dev) if d.manageIp: of.write("Device Id %s \t Device Title %s \t Device manageIp %s \n" % (d.id, d.title, d.manageIp)) else: of.write("Device Id %s \t Device Title %s \t Device manageIp NO IP ADDRESS \n" % (d.id, d.title)) of.close()
try: with open(os.devnull, 'w') as devnull: subprocess.check_call(['sudo', 'rabbitmqctl', '-p', vhost, 'clear_permissions', user], stdout=devnull) subprocess.check_call(['sudo', 'rabbitmqctl', '-p', vhost, 'set_permissions', user, 'zenoss.openstack.*', 'zenoss.openstack.*', '^$'], stdout=devnull) except subprocess.CalledProcessError, e: sys.exit("Unable to exceute rabbitmqctl (%s)" % e) if __name__ == '__main__': if not VERSION5: require_rabbitmq() create_exchanges() # Log into ZODB.. try: script = ZenScriptBase() script.connect() dmd = script.dmd except Exception, e: sys.exit("Unable to connect to ZODB: %s" % e) create_default_credentials(dmd) if not VERSION5: provision_user(dmd) rabbit_ip = {} if VERSION5: from Products.ZenUtils.controlplane.application import getConnectionSettings from Products.ZenUtils.controlplane import ControlPlaneClient
root = ET.Element(roottag) _convert_dict_to_xml_recurse(root, xmldict, listnames) return root def dict2xml(datadict, roottag='data', listnames=None, pretty=False): """Converts a dictionary to an UTF-8 encoded XML string. """ root = dict2et(datadict, roottag, listnames) return to_string(root, pretty=True) print "*****START*****" # Setup dmd object # NOTE: Do I need this in daemon? dmd = ZenScriptBase(connect=True).dmd # Initialize lists slots=[None]*maxSlots # Use zxconfig.xml to set up slot/IP Addr map. try: configFile = open(zxconfigFileName) except IOError: # NOTE: Send event & log error & QUIT print "Unable to find zxconfig.xml" # Quit. zxconfig.xml must be present for initialization. sys.exit() configDoc = parse(configFile)
def get_zodb_connection(): print("Connecting to zodb...") from Products.ZenUtils.ZenScriptBase import ZenScriptBase return ZenScriptBase(connect=True).dmd
def process_config_changes(): """Determine if chassis or Zenoss configuration has changed and process any changes. """ #Determine if chassis or Zenoss configuration has changed and process any changes. print("process_config_changes") global slots global groupName global boardRemoved global boardAdded global boardHotSwap global boardUnchanged global boardUnhealthy global noneMState global actReqMState global actMState global fruActiveMState global shelfMgrClass global zxsbcClass global znyxPrefix global nonZnyxPrefix # Get dmd dmd = ZenScriptBase(connect=True).dmd # CHASSIS CHANGES newSlots=[None]*maxSlots slotStatus=[None]*maxSlots # Initialize IP addresses in new table. for slotNum in range (0,len(slots)): newSlots[slotNum] = {'ip': slots[slotNum]['ip']} # Derive the device class from the device itself. Then get the latest serial number and # mstate from the shelf manager. # NOTE: Order is important. Call setup_chassis before get_device_name. setup_chassis(newSlots) # If unable to contact shelf manager then return. if newSlots[0]['status'] == "unreachable": print ("process_config_changes: can't contact shelf manager") return get_device_classes(newSlots) for slotNum in range (1,len(newSlots)): newSlotInfo = newSlots[slotNum] slotInfo = slots[slotNum] # Error condition. Neither of these will be empty. if newSlotInfo == None or slotInfo == None: # Generate event print "zxchassisdaemon: Empty slot info (internal data)" continue # If can't get new slot info then continue. if newSlotInfo['status'] == "unreachable": continue # Retrieve serial number and mstate. newSerial = newSlotInfo['serial'] newMState = int(newSlotInfo['mstate']) newClass = newSlotInfo['class'] oldSerial = slotInfo['serial'] oldMState = int(slotInfo['mstate']) oldClass = slotInfo['class'] if newMState == noneMState: if oldMState == noneMState or oldClass == None or oldSerial == None: # No Change -- slot still empty. slotStatus[slotNum] = boardUnchanged else: # Board Removed. slotStatus[slotNum] = boardRemoved elif newMState == fruActiveMState or newMState == actReqMState or newMState == actMState: if ((oldMState == noneMState) or (oldClass == None) or (oldSerial == None)): # Board Added slotStatus[slotNum] = boardAdded print("BOARD ADDED: newSerial = %s, newMState= %s, newClass= %s" % (newSerial, newMState, newClass)) print("oldSerial = %s, oldMState= %s, oldClass= %s" % (oldSerial, oldMState, oldClass)) elif (newSerial != oldSerial) or (newClass != oldClass): # Hot Swap slotStatus[slotNum] = boardHotSwap print("BOARD HOTSWAP: newSerial = %s, newMState= %s, newClass= %s" % (newSerial, newMState, newClass)) print("oldSerial = %s, oldMState= %s, oldClass= %s" % (oldSerial, oldMState, oldClass)) else: # No Change slotStatus[slotNum] = boardUnchanged else: # Board is inactive, deactivating, or not communicating. # Delete device if it exists. slotStatus[slotNum] = boardUnhealthy # ZENOSS CHANGES foundDevices=[False]*maxSlots for device in dmd.Devices.getSubDevices(): groups = device.getDeviceGroupNames() for a in range (0,len(groups)): if groups[a].find(groupName) != -1: slot = device.rackSlot slotWords = (str(slot)).split() zenossSlotNum = int(slotWords[len(slotWords)-1]) serialNum = device.getHWSerialNumber() name = device.getDeviceName() ip = device.getManageIp() classPath = device.getDeviceClassPath() classPath.strip() classes = classPath.split('/') className = classes[len(classes)-1] # User could have changed slot, serial, ip, name or class. # Zenoss modeling will reset slot & serial, so don't worry about these. # NOTE: Znyx will reset slot & serial in private MIB. This slot number # is not guaranteed to correspond to chassis slot. # Try to find slot by finding a match for the IP address. # If there's no match, then delete the device. # Changing the IP address is not allowed. for slotNum in range (0,len(slots)): if ip == slots[slotNum]['ip']: break if slotNum >= len(slots): print("process_config_changes: invalid managed IP = %s" % ip) continue foundDevices[slotNum] = True # User not allowed to change IP address in first release. # Change it back & generate event. # NOTE: Test changing IP later. # User not allowed to change class. # Change it back & generate event. if className != slots[slotNum]['class'] and className != newSlots[slotNum]['class']: print("process_config_changes: user changed device class to %s" % className) if (newSlots[slotNum]['class'] == shelfMgrClass) or (newSlots[slotNum]['class'] == zxsbcClass): prefix = nonZnyxPrefix else: prefix = znyxPrefix newClassPath = prefix + newSlots[slotNum]['class'] print("slotNum = %s" % slotNum) print("newClassPath = %s" % newClassPath) device.moveDevices(newClassPath,device.id) # User can change name...This is OK. Just update internal tables. newSlots[slotNum]['zname'] = name for slotNum in range (1,len(newSlots)): status = slotStatus[slotNum] if status == None: continue if newSlots[slotNum]['status'] == "unreachable": continue # Check for case where user might have deleted a valid device in Zenoss. # This would be a user error that should be corrected. if (status == boardUnchanged): if (newSlots[slotNum]['class'] != None) and (foundDevices[slotNum] == False): status = boardAdded else: continue if (status == boardUnhealthy): continue if status == boardRemoved: if foundDevices[slotNum] == True: device = dmd.Devices.findDevice(slots[slotNum]['ip']) # Delete device. if not device: print("cannot find device in slot %s to delete" % slotNum) else: device.deleteDevice() commit() learSlot(slotNum) else: newSlotInfo = newSlots[slotNum] newIp = newSlotInfo['ip'] #newName = newSlotInfo['zname'] newClass = newSlotInfo['class'] newSerial = newSlotInfo['serial'] if (newClass == shelfMgrClass) or (newClass == zxsbcClass): prefix = nonZnyxPrefix else: prefix = znyxPrefix newClassPath = prefix + newClass if (status == boardAdded): # Get new name. get_device_name(newSlotInfo) newName = newSlotInfo['zname'] # Add new device via Zenoss. print("add for boardAdded") add_dmd_device(newIp, newName, newClassPath, groupName, slotNum, newSerial) else: # Hot Swap # If different class, then delete old device and add new one. # Otherwise, generate event. if (newClass != slots[slotNum]['class']): if foundDevices[slotNum] == True: device = dmd.Devices.findDevice(slots[slotNum]['ip']) if not device: print("cannot find device in slot %s to delete" % slotNum) else: device.deleteDevice() commit() clearSlot(slotNum) # Get new name. get_device_name(newSlotInfo) newName = newSlotInfo['zname'] print("add for hotswap: slotNum=%s, newIP=%s, newClass = %s, slots['class']= %s" % (slotNum, newIp, newClass, slots[slotNum]['class'])) # Add new device via Zenoss add_dmd_device(newIp, newName, newClassPath, groupName, slotNum, newSerial) else: print ("zxchassisdaemon: Hot swap in slot = %s." % str(slotNum)) slots[slotNum]['ip'] = newIp slots[slotNum]['zname'] = newSlotInfo['zname'] slots[slotNum]['class'] = newClass slots[slotNum]['serial'] = newSerial dmd.Devices.reIndex() commit()
def run(processor_count=8, hard=False, root="", indexes=None, types=(), terminator=None, toggle_debug=None): if hard and (root or indexes or types): raise Exception( "Root node, indexes, and types can only be specified during soft re-index" ) log.info("Beginning {0} redindexing with {1} child processes.".format( "hard" if hard else "soft", processor_count)) start = time.time() log.info("Initializing model database and Solr model catalog...") dmd = ZenScriptBase(connect=True).dmd index_client = init_model_catalog() processes = [] error_queue = multiprocessing.Queue() parent_queue = multiprocessing.Queue() counter = multiprocessing.Value(ctypes.c_uint32) semaphore = multiprocessing.Semaphore(processor_count) cond = multiprocessing.Condition() if not terminator: terminator = multiprocessing.Event() cancel = multiprocessing.Event() processes_remaining = 0 work = [] Worker = None proc_start = time.time() def hard_index_is_done(): return terminator.is_set() or (semaphore.get_value() == 0 and parent_queue.empty()) def soft_index_is_done(): return cancel.is_set() or terminator.is_set() # In the case of early termination, we only want to wait up to 30 seconds # In the case of straggler processes, we wait up to an hour def get_timeout(): if terminator.is_set(): return 30 return 3600 if hard: log.info("Clearing Solr data") index_client.clear_data() work.append("/zport") Worker = HardReindex is_done = hard_index_is_done else: log.info("Reading uids from Solr") work = get_uids(index_client, root, types) Worker = SoftReindex is_done = soft_index_is_done log.info("Starting child processes") for n in range(processor_count): p = Worker(error_queue, n, processor_count, parent_queue, counter, semaphore, cond, cancel, terminator, indexes, toggle_debug) processes.append(p) p.start() for uid in work: parent_queue.put(uid) if not hard: # Put the terminate sentinel at the end of the queue parent_queue.put(TERMINATE_SENTINEL) log.info("Waiting for processes to finish") lastcount = 0 last = start while True: with cond: # soft_index_is_done is actually appropriate in both cases if soft_index_is_done(): log.info("Terminating condition met. Done!") cancel.set() # In case we were terminated before we were waiting cond.notify_all() break cond.wait() checkLogging(toggle_debug) try: # Print any errors we've built up while not error_queue.empty(): try: idx, exc = error_queue.get_nowait() except Queue.Empty: pass # This shouldn't happen, but just in case there's a race somehow else: log.error( "Indexing process {0} encountered an exception: {1}" .format(idx, exc)) # Print status with counter.get_lock(): delta = counter.value - lastcount if delta > MODEL_INDEX_BATCH_SIZE: now = time.time() persec = delta / (now - last) last, lastcount = now, counter.value log.info("Indexed {0} objects ({1}/sec)".format( lastcount, persec)) # Check to see if we're done log.debug("{0} workers still busy".format( semaphore.get_value())) log.debug("parent queue is {0}empty".format( "" if parent_queue.empty() else "not ")) if is_done(): # All workers are idle and there's no more work to do, so the end log.info("Terminating condition met. Done!") cancel.set() break finally: # Pass the ball back to the child that notified cond.notify_all() log.info("Indexing complete, waiting for workers to clean up") for proc in processes: log.debug("Joining proc {0}".format(proc.idx)) proc.join(get_timeout()) if proc.is_alive(): log.warn( "Worker {} did not exit within timeout, terminating...".format( proc.idx)) proc.terminate() end = time.time() log.info("Total time: {0}".format(end - start)) log.info("Time to initialize: {0}".format(proc_start - start)) log.info("Time to process and reindex: {0}".format(end - proc_start)) log.info("Number of objects indexed: {0}".format(counter.value))