class renameCollectionItemsRelations(Migrate.Step): version = Migrate.Version(3, 0, 0) def cutover(self, dmd): reportclass = dmd.Reports._getOb('Multi-Graph Reports') for report in reportclass.reports(): # if this item does not have a 'collections' attribute # go on to the next try: rptcolls = report.collections except AttributeError: continue # for every collection attached to this report, # change the 'items' relation to 'collection_items' for coll in rptcolls(): rel = coll.items if isinstance(rel, ToManyContRelationship): obs = [] for ob in rel(): obs.append(aq_base(ob)) remote_rel = ob.collection remote_rel._remove(coll) rel._remove(ob) coll._delObject('items') coll.buildRelations() newrel = coll.collection_items.primaryAq() for ob in obs: newrel._setObject(ob.getId(), ob) ob = newrel._getOb(ob.getId()) assert ob.__primary_parent__ == newrel assert ob.collection() == coll assert ob in newrel()
class RunCommandsPermission(Migrate.Step): version = Migrate.Version(2, 2, 0) def cutover(self, dmd): dmd.zport.manage_permission(ZEN_RUN_COMMANDS, [ZEN_USER_ROLE, ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
class UpdateOSProcessClasses(Migrate.Step): " Update default OSProcess classes templates to make them work in 5.x " version = Migrate.Version(5, 0, 70) def cutover(self, dmd): f = getFacade('process') classes = dmd.Processes.Zenoss.getSubOSProcessClassesSorted() for klass in classes: path = '/zport/dmd/Processes/Zenoss/osProcessClasses/%s' % klass.id if klass.id in DEPRECATED: try: f.deleteNode(path) continue except Exception as e: log.error( "Unable to remove depricated OSProcess class %s: %s" % (klass, e)) if klass.id in TEMPLATE: try: f.setInfo(path, {'includeRegex': TEMPLATE[klass.id]}) except Exception as e: log.error("Unable to update OSProcess class %s: %s" % (klass, e))
class UpdateZopeDeadlockIntervalKillCount(Migrate.Step): """ Update the deadlock healthcheck to all of the zopes. """ version = Migrate.Version(300, 0, 10) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return zopes = filter( lambda s: s.name.lower( ) in ["zope", "zauth", "zenapi", "zendebug", "zenreports"], ctx.services) log.info("Found %i Zope services." % len(zopes)) for z in zopes: deadlockChecks = filter( lambda healthCheck: healthCheck.name == "deadlock_check", z.healthChecks) if not deadlockChecks: log.warn("Unable to find the zope deadlock healthcheck") continue else: for check in deadlockChecks: check.interval = 60 check.kill_count_limit = 5 ctx.commit()
class ReportsNotPackable(Migrate.Step): version = Migrate.Version(2, 1, 0) def cutover(self, dmd): if dmd.zenMenus.Report_list.zenMenuItems._getOb('addToZenPack', False): dmd.zenMenus.Report_list.zenMenuItems._delObject('addToZenPack')
class RemoveCommandsEditPermission(Migrate.Step): version = Migrate.Version(4, 0, 0) def cutover(self, dmd): dmd.zport.manage_permission(ZEN_DEFINE_COMMANDS_EDIT, [MANAGER_ROLE], 1)
class FixZenpop3LogFilter(Migrate.Step): """Correct the LogFilter for /opt/zenoss/log/zenpop3.log""" version = Migrate.Version(200, 0, 0) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return services = filter(lambda s: s.name == "zenpop3", ctx.services) log.info("Found %d services named 'zenpop3'." % len(services)) changed = False for service in services: for logConfig in service.logConfigs: if logConfig.path == "/opt/zenoss/log/zenpop3.log": if logConfig.filters[0] != "pythondaemon": log.info("Updating logfilter for %s", logConfig.path) logConfig.filters[0] = "pythondaemon" changed = True else: log.info( "No updates necesary for the logfilter for %s", logConfig.path) if changed: # Commit our changes. ctx.commit()
class UpdateMariaDBPoolAlloc(Migrate.Step): version = Migrate.Version(108, 0, 0) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return mariaservices = filter(lambda s: "mariadb" in s.name, ctx.services) log.info( "Found {0} services with 'mariadb' in their service path".format( len(mariaservices))) for m in mariaservices: log.info("{0}".format(m)) cfs = filter(lambda f: f.name == "/etc/my.cnf", m.originalConfigs + m.configFiles) for cf in cfs: lines = cf.content.split('\n') for i, line in enumerate(lines): if line.startswith( "innodb_buffer_pool_size") and "512M" in line: lines[i] = line.replace( "512M", "{{percentScale .RAMCommitment 0.8}}") log.info( "Changed MariaDB innodb_buffer_pool_size from 512M (default) to '{{percentScale .RAMCommitment 0.8}}' on line {0}" .format(i)) cf.content = '\n'.join(lines) # Commit our changes. ctx.commit()
class zWmiMonitorProperty(Migrate.Step): version = Migrate.Version(2, 0, 0) def cutover(self, dmd): # Set zWmiMonitorIgnore defaults if not dmd.Devices.hasProperty("zWmiMonitorIgnore"): dmd.Devices._setProperty("zWmiMonitorIgnore", True, type="boolean") else: dmd.Devices._updateProperty('zWmiMonitorIgnore', True) try: win = dmd.Devices.getOrganizer("/Server/Windows") if not win.hasProperty("zWmiMonitorIgnore"): win._setProperty("zWmiMonitorIgnore", False, type="boolean") else: win._updateProperty('zWmiMonitorIgnore', False) except KeyError: pass # Delete misspelled zProp for dc in dmd.Devices.getSubOrganizers(): if dc.hasProperty('zWmiMonitorIgoner'): dc._delProperty('zWmiMonitorIgoner') for dev in dmd.Devices.getSubDevicesGen(): if dev.hasProperty('zWmiMonitorIgoner'): dev._delProperty('zWmiMonitorIgoner')
class DisableZproxyAccessLog(Migrate.Step): "Disable zproxy nginx access logging by default" version = Migrate.Version(108, 0, 0) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return zproxy_service = ctx.getTopService() if not zproxy_service: log.info("No top service found, skipping") return # Update zproxy-nginx.conf. cfs = filter( lambda f: f.name == "/opt/zenoss/zproxy/conf/zproxy-nginx.conf", zproxy_service.originalConfigs + zproxy_service.configFiles) log.info( "Found %i config files named '/opt/zenoss/zproxy/conf/zproxy-nginx.conf'." % len(cfs)) for cf in cfs: cf.content = re.sub( r'^(\s*access_log)\s+/opt/zenoss/zproxy/logs/access.log;', r'\1 off;', cf.content, 0, re.MULTILINE) log.info("Disabled zproxy nginx access logging") # Commit our changes. ctx.commit()
class DeviceTemplatesProperty(Migrate.Step): version = Migrate.Version(2, 0, 0) def cutover(self, dmd): if not dmd.Devices.hasProperty("zDeviceTemplates"): dmd.Devices._setProperty("zDeviceTemplates", ["Device"], type="lines")
class ZenPackDataSources(Migrate.Step): version = Migrate.Version(2, 0, 0) def cutover(self, dmd): from Products.ZenModel.BasicDataSource import BasicDataSource from Products.ZenModel.RRDDataSource import RRDDataSource try: from Products.ZenWeb.datasources.PageCheckDataSource \ import PageCheckDataSource except ImportError: PageCheckDataSource = None numDS = 0 numUnhandled = 0 for t in dmd.Devices.getAllRRDTemplates(): for s in t.datasources(): if s.__class__ == RRDDataSource: numDS += 1 if PageCheckDataSource and s.sourcetype == 'PAGECHECK': s.__class__ = PageCheckDataSource else: s.__class__ = BasicDataSource elif issubclass(s.__class__, RRDDataSource): pass else: numUnhandled += 1 sys.stderr.write('ZenPackDataSources can\'t handle datasource' + \ ' type %s\n' % (s.__class__)) print 'Converted %s DataSources' % numDS if numUnhandled: print 'Problems with %s DataSources' % numUnhandled
class UpdateLocalhostTemplate(Migrate.Step): version = Migrate.Version(5, 0, 0) def cutover(self, dmd): collectorTemplate = dmd.unrestrictedTraverse( '/zport/dmd/Monitors/rrdTemplates/PerformanceConf', None) if not collectorTemplate is None: datasourcesToRemove = ('zenwin', 'zeneventlog') # find the datasources and remove them for datasource in datasourcesToRemove: if collectorTemplate.datasources._getOb(datasource, None): collectorTemplate.datasources._delObject(datasource) # now make sure that these datasources are not in the graphs for graph in collectorTemplate.graphDefs(): for datasource in datasourcesToRemove: if graph.graphPoints._getOb(datasource, None): graph.graphPoints._delObject(datasource) # event queue log named these graph points terribly so search for them eventQueueGraph = collectorTemplate.graphDefs._getOb( 'Event Queue', None) if eventQueueGraph is None: return for datasource in datasourcesToRemove: for p in eventQueueGraph.graphPoints(): if hasattr(p, 'dpName') and datasource in p.dpName: p.graphPoints._delObject(p.id) # remove the cycle points graph since we don't collect this metric anymore if collectorTemplate.graphDefs._getOb('Data Points', None): collectorTemplate.graphDefs._delObject('Data Points')
class FixRabbitmqHealthCheck(Migrate.Step): """fix broken rabbitmq endpoints """ version = Migrate.Version(300, 0, 1) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return commit = False for svc in ctx.services: rmqs = filter( lambda ep: ep.name == "rabbitmq" and ep.purpose == "import", svc.endpoints ) log.info("updating a rabbitmq endpoint for service '%s'.", svc.name) for rmq in rmqs: rmq.applicationtemplate = u'rabbitmq.*' rmq.application = u'rabbitmq.*' rmq.protocol = "" rmq.portnumber = 0 commit = True if commit: ctx.commit()
class addzUsesManageIp(Migrate.Step): version = Migrate.Version(200, 0, 1) def cutover(self, dmd): if not hasattr(dmd.Devices, 'zUsesManageIp'): dmd.Devices._setProperty('zUsesManageIp', True, type='boolean')
class ChangeDefaultZauthZserverThreads(Migrate.Step): version = Migrate.Version(111, 0, 0) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return zauths = filter(lambda s: s.name == "Zauth", ctx.services) if not zauths: log.info("Couldn't find Zauth service, skipping.") return log.info("Found Zauth service.") commit = False for service in zauths: zauthZopeConfs = filter( lambda config: config.name.endswith("zauth-zope.conf"), service.configFiles) for config in zauthZopeConfs: config.content = re.sub(r'zserver-threads \d+', r'zserver-threads 7', config.content) commit = True if commit: log.info("Committing changes.") ctx.commit()
class ifOperStatusEthernetCsmacd64(Migrate.Step): version = Migrate.Version(4, 2, 0) def cutover(self, dmd): if hasattr(dmd.Devices.rrdTemplates, 'ethernetCsmacd_64'): template = dmd.Devices.rrdTemplates._getOb('ethernetCsmacd_64') if not hasattr(template.datasources, "ifOperStatus"): bds = BasicDataSource('ifOperStatus') bds.oid = ".1.3.6.1.2.1.2.2.1.8" bds.sourcetype = "SNMP" template.datasources._setObject('ifOperStatus', bds) bds = template.datasources.ifOperStatus bds.addDataPoints() datapoint = template.datasources.ifOperStatus.datapoints.ifOperStatus datapoint.createCmd = "\n".join(( 'RRA:LAST:0.5:1:600', 'RRA:AVERAGE:0.5:1:600', # every 5 mins for 2 days 'RRA:AVERAGE:0.5:6:600', # every 30 mins for 12 days 'RRA:AVERAGE:0.5:24:600', # every 2 hours for 50 days 'RRA:AVERAGE:0.5:288:600', # every day for 600 days 'RRA:MAX:0.5:6:600', 'RRA:MAX:0.5:24:600', 'RRA:MAX:0.5:288:600', ))
class AddOOMParams(Migrate.Step): "Add OOMKillDisable and OOMScoreAdj parameters to db services" version = Migrate.Version(300, 0, 10) def cutover(self, dmd): cc_version = parse_version(getCCVersion()) if cc_version < parse_version("1.6.5"): log.info("Require CC version >= 1.6.5, skipping") return try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return service_names = [ 'mariadb-model', 'redis', 'Impact', 'Solr', 'mariadb-events' ] services = filter(lambda s: s.name in service_names, ctx.services) log.info("Found %i services", len(services)) for service in services: service.oomKillDisable = True service.oomScoreAdj = 0 ctx.commit()
class addDeviceIpAddrRelation(Migrate.Step): version = Migrate.Version(300, 0, 0) def cutover(self, dmd): log.info("Updating relationships on Ip Addresses") catalog = IModelCatalogTool(dmd.Networks) for ip in catalog.search(IpAddress): try: ip.getObject().buildRelations() #some objects can fail relations building process except (Exception, ): continue log.info("Updating relationships on Devices") for dev in dmd.Devices.getSubDevices(): try: dev.buildRelations() if dev.manageIp: ipobj = dev.getNetworkRoot().findIp(dev.manageIp) if ipobj: dev.ipaddress.addRelation(ipobj) else: ipWithoutNetmask, netmask = ipAndMaskFromIpMask( dev.manageIp) ipobj = dev.getNetworkRoot().createIp( ipWithoutNetmask, netmask) dev.ipaddress.addRelation(ipobj) notify(IndexingEvent(ipobj)) #some objects can fail relations building process except (Exception, ): continue
class zNmapPortscanOptions(Migrate.Step): version = Migrate.Version(3, 0, 0) #try to migrate any other properties that still contain ";" instead of " " def _tryMigrate(self, path, dmd): obj = dmd.getObjByPath('/zport/dmd/Devices%s' % path) if not obj: return oldopts = obj.zNmapPortscanOptions if oldopts.find("${here/") > -1: return newopts = oldopts.replace(";", " ") newopts += " ${here/manageIp}" log.debug("replacing zNmapPortscanOptions at %s from '%s' to '%s'" % (path, oldopts, newopts)) obj._updateProperty("zNmapPortscanOptions", newopts) def cutover(self, dmd): try: #in case the property doesn't exist (unlikely) if not hasattr(aq_base(dmd.Devices), 'zNmapPortscanOptions'): log.info("creating zNmapOptions") dmd.Devices._setProperty( "zNmapPortscanOptions", "-p 1-1024 -sT --open -oG - ${here/manageIp}") #take care of all others ppaths = [] for d in dmd.Devices.getSubDevices(): ppath = d.zenPropertyPath("zNmapPortscanOptions") if not ppath in ppaths: ppaths.append(ppath) self._tryMigrate(ppath, dmd) except Exception as e: log.error(str(e)) pass
class AddAuditLogFlag(Migrate.Step): """ Add boolean flag to indicate which logs are audit logs.""" version = Migrate.Version(114, 0, 0) def cutover(self, dmd): log = logging.getLogger("zen.migrate") try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return changed = False for service in ctx.services: if not service.logConfigs: continue for config in service.logConfigs: if config.path == "/opt/zenoss/log/audit.log" and \ not config.isAudit: config.isAudit = True changed = True if changed: ctx.commit() else: log.info('Nothing to change in this migration step.')
class AddIndexesForDevice(Migrate.Step): """ Adds new indexes for devices in scope of adding new router which gives a possibility to pull data directly from SOLR without touching ZODB. """ version = Migrate.Version(300, 0, 1) def cutover(self, dmd): search_results = IModelCatalogTool(dmd).devices.search(limit=1, fields=["pythonClass"]) if search_results.total > 0 and search_results.results.next().pythonClass is None: log.info("Performing of adding new indexes for devices, this can take a while.") reindex_model_catalog(dmd, root="/zport/dmd/Devices", idxs=("tagNumber", "pythonClass", "priority", "collector", "osModel", "osManufacturer", "hwModel", "hwManufacturer", "serialNumber"), types=DeviceIndexable)
class MoveHistoryToMoreMenu(Migrate.Step): version = Migrate.Version(2, 2, 0) def cutover(self, dmd): # Build menus dmd.buildMenus({ 'More': [{ 'action': 'viewHistoryEvents', 'allowed_classes': [ 'EventClass', 'EventClassInst', 'Device', 'DeviceOrganizer', 'Location', 'System', 'DeviceClass' ], 'banned_classes': ['IpNetwork'], 'description': 'Event History', 'id': 'historyEvents', 'ordering': 1.0, 'permissions': (ZEN_VIEW, ) }] }) viewHistory = dmd.zenMenus.More.zenMenuItems.viewHistory if not viewHistory.banned_classes: viewHistory.banned_classes = ('IpNetwork', )
class addUnixMonitoring(Migrate.Step): version = Migrate.Version(2, 5, 0) def cutover(self, dmd): server = dmd.findChild('Devices/Server') sshId = 'SSH' if not sshId in server.childIds(): server.manage_addOrganizer(sshId) ssh = server.findChild(sshId) ssh.setZenProperty('zSnmpMonitorIgnore', True) ssh.setZenProperty('zCollectorPlugins', []) else: #previous versions added the zProps incorrectly ssh = server.findChild(sshId) from Acquisition import aq_base if hasattr(aq_base(ssh), 'zSnmpMonitorIgnore'): del ssh.zSnmpMonitorIgnore ssh.setZenProperty('zSnmpMonitorIgnore', True) if hasattr(aq_base(ssh), 'zCollectorPlugins'): del ssh.zCollectorPlugins ssh.setZenProperty('zCollectorPlugins', []) ssh = server.findChild(sshId) linuxId = 'Linux' if not linuxId in ssh.childIds(): ssh.manage_addOrganizer(linuxId)
class FixCmdEventClass(Migrate.Step): version = Migrate.Version(4, 2, 70) def cutover(self, dmd): # make sure the following event classes exist. eventClasses = [] paths = ('/Cmd', '/Cmd/Ok', '/Cmd/Fail', '/Conn', '/Conn/Fail') for path in paths: # createOrganizer will either create or return the existing event class eventClasses.append(dmd.Events.createOrganizer(path)) # if ZenWinPerf is installed remove the classes from packable. try: pack = dmd.ZenPackManager.packs._getOb( 'ZenPacks.zenoss.ZenWinPerf') for ec in eventClasses: try: pack.packables.removeRelation(ec) except ObjectNotFound: log.debug( "%s is not in the packable relationship for ZenWinPerf", ec) except AttributeError: log.debug( "Skipping removing packable relationship because ZenWinPerf is not installed" )
class ZProxyViaSupervisorD(Migrate.Step): """Run zproxy via supervisord.""" version = Migrate.Version(200, 0, 0) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return zproxy = ctx.getTopService() commit = False if zproxy.startup.startswith('redis-server'): zproxy.startup = "/bin/supervisord -n -c /etc/zproxy/zproxy_supervisor.conf" zsc = sm.ConfigFile(name='/etc/zproxy/zproxy_supervisor.conf', filename='/etc/zproxy/zproxy_supervisor.conf', owner='zenoss:zenoss', permissions='644', content=zproxy_supervisord_conf) zproxy.configFiles.append(zsc) zproxy.originalConfigs.append(zsc) commit = True if commit: ctx.commit()
class RemoveEmptyGraphData(Migrate.Step): """Remove some graph datapoints from a few services.""" version = Migrate.Version(5, 0, 70) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return zenmodelers = filter(lambda s: s.name == "zenmodeler", ctx.services) log.info("Found %i services named 'zenmodeler'." % len(zenmodelers)) remove_metrics = ["dataPoints", "eventCount", "missedRuns", "taskCount"] remove_graphs = ["dataPoints", "events", "missedRuns", "tasks"] for zenmodeler in zenmodelers: for mc in zenmodeler.monitoringProfile.metricConfigs: before = len(mc.metrics) mc.metrics = [m for m in mc.metrics if m.ID not in remove_metrics] after = len(mc.metrics) log.info("Removed %i metrics from zenmodeler." % (before - after)) before = len(zenmodeler.monitoringProfile.graphConfigs) zenmodeler.monitoringProfile.graphConfigs = [ gc for gc in zenmodeler.monitoringProfile.graphConfigs if gc.graphID not in remove_graphs] after = len(zenmodeler.monitoringProfile.graphConfigs) log.info("Removed %i graphs from zenmodeler." % (before - after)) # Commit our changes. ctx.commit()
class UpdatePermsForAdvancedPage(Migrate.Step): version = Migrate.Version(300, 0, 4) def addPermissions(self, obj, permission, roles=None, acquire=0): if not roles: roles = [] if permission not in obj.possible_permissions(): obj.__ac_permissions__ = (obj.__ac_permissions__ + ((permission, (), roles), )) for permissionDir in obj.rolesOfPermission(permission): if permissionDir['selected']: if permissionDir['name'] not in roles: roles.append(permissionDir['name']) obj.manage_permission(permission, roles, acquire) def cutover(self, dmd): zport = dmd.zport # update permission to see UI settings page for ZEN_MANAGER. self.addPermissions( zport, ZEN_MANAGE_UI_SETTINGS, [OWNER_ROLE, MANAGER_ROLE, ZEN_MANAGER_ROLE, CZ_ADMIN_ROLE], 1) # update permission to see Event configuration page for ZEN_MANAGER. self.addPermissions( zport, ZEN_MANAGE_EVENT_CONFIG, [OWNER_ROLE, MANAGER_ROLE, ZEN_MANAGER_ROLE, CZ_ADMIN_ROLE], 1)
class addPreferSnmpNamingFlag(Migrate.Step): version = Migrate.Version(3, 0, 0) def cutover(self, dmd): if not hasattr(dmd.Networks, 'zPreferSnmpNaming'): dmd.Networks._setProperty('zPreferSnmpNaming', False, 'boolean') transaction.commit()
class AddQuiltInstallCommand(Migrate.Step): """Add `quilt-install` command to Zope service""" version = Migrate.Version(5, 0, 70) def cutover(self, dmd): try: ctx = sm.ServiceContext() except sm.ServiceMigrationError: log.info("Couldn't generate service context, skipping.") return quilt_install_command = Command( 'install-quilt', '${ZENHOME:-/opt/zenoss}/bin/zenrun quilt.sh install', commitOnSuccess=False) zope_services = filter(lambda s: s.name == "Zope", ctx.services) log.info("Found %i services named 'Zope'." % len(zope_services)) for zope_service in zope_services: # Add `install-quilt` if it is not already present if not filter(lambda c: c.name == 'install-quilt', zope_service.commands): log.info("Added install-quilt command.") zope_service.commands.append(quilt_install_command) else: log.info("Install-quilt command alread present.") # Commit our changes. ctx.commit()