def process(self, device, results, log): log.info("Modeler %s processing data for device %s", self.name(), device.id) matcher = re.compile(r'^(?P<version>[\d\.]+)') for line in results.split('\n'): match = matcher.search(line) if match: version = match.group('version') productKey = get_productKey(version) openstack_om = ObjectMap({ 'compname': 'os', 'setProductKey': MultiArgs(productKey, 'OpenStack') }) return [ ObjectMap({ 'setApplyDataMapToOpenStackInfrastructureEndpoint': openstack_om }) ] return []
def process(self, device, results, log): """Process collect's results. Return iterable of datamaps.""" state, results = results for tabledata in results: state.update_iftable(tabledata) clientmacs = set() maps = [] for iface_id, data in state.iftable.items(): clientmacs.update(data['clientmacs']) maps.append( ObjectMap({ 'compname': 'os', 'relname': 'interfaces', 'id': iface_id, 'clientmacs': list(set(data['clientmacs'])), 'baseport': data['baseport'], })) if not state.macs_indexed and state.iftable: reindex_map = ObjectMap({'set_reindex_maps': clientmacs}) maps.insert(0, reindex_map) return maps
def process(self, device, results, log): #log.debug(' Start of process - results is %s \n' % (results)) maps = [] for host in results: # Don't actually see there being more than one host..... hostDict = {} hostDict['setOSProductKey'] = host.summary.config.product.fullName hostDict['setHWProductKey'] = host.summary.hardware.model hostDict['cpuMhz'] = long(host.summary.hardware.cpuMhz) hostDict['cpuModel'] = host.summary.hardware.cpuModel hostDict['numCpuCores'] = int(host.summary.hardware.numCpuCores) hostDict['numCpuPkgs'] = int(host.summary.hardware.numCpuPkgs) hostDict['numCpuCoresPerPkgs'] = hostDict['numCpuCores'] / hostDict['numCpuPkgs'] hostDict['numCpuThreads'] = int(host.summary.hardware.numCpuThreads) hostDict['numNics'] = int(host.summary.hardware.numNics) vmotionState = host.summary.config.vmotionEnabled if vmotionState == 0: hostDict['vmotionState'] = True else: hostDict['vmotionState'] = False log.debug(' hostDict is %s \n' % (hostDict)) maps.append(ObjectMap({'totalMemory': host.summary.hardware.memorySize }, compname='hw')) maps.append(ObjectMap({'totalSwap': 0}, compname='os')) maps.append(ObjectMap( modname = 'ZenPacks.community.VMwareESXiMonitorPython.ESXiHost', data = hostDict )) return maps
def process(self, device, results, log): """collect WMI information from this device""" log.info('processing %s for device %s', self.name(), device.id) try: cs = results.get('Win32_ComputerSystem', [None])[0] os = results.get('Win32_OperatingSystem', [None])[0] if not (cs and os): return maps = [] om = self.objectMap(cs) om.snmpLocation = '' om.snmpOid = '' om.setOSProductKey = MultiArgs(os['_name'].split('|')[0], 'Microsoft') om.setHWProductKey = MultiArgs(cs['_model'], cs['_manufacturer']) sn = str( results.get('Win32_SystemEnclosure', [{ 'sn': '' }])[0]['sn'] or '').strip() if sn: om.setHWSerialNumber = sn maps.append(om) maps.append( ObjectMap({"totalMemory": (os.get('totalMemory', 0) * 1024)}, compname="hw")) maps.append( ObjectMap({"totalSwap": (os.get('totalSwap', 0) * 1024)}, compname="os")) except: log.warning('processing error') return return maps
def process(self, device, results, log): log.info("Modeler %s processing data for device %s", self.name(), device.id) results = results_from_result(results) if len(results) != 3: LOG.error( "Unable to process results. Expected 3 results, but got %d (%s)", len(results), results) return [] hostname, hostname_f, dnsdomainname = results # the FQDN could be either "hostname -f", or "hostname" + "dnsdomainname" fqdn = hostname_f if "." not in hostname and len(dnsdomainname) > 0: merged_fqdn = hostname + '.' + dnsdomainname else: merged_fqdn = "" # pick the longer of the two if len(merged_fqdn) > len(fqdn): fqdn = merged_fqdn hostfqdn_om = ObjectMap({'hostfqdn': fqdn, 'hostlocalname': hostname}) LOG.info("Hostname: %s (%s)", hostname, fqdn) return [ ObjectMap( {'setApplyDataMapToOpenStackInfrastructureHost': hostfqdn_om}) ]
def parse_result(self, dsconfs, result): if result.exit_code != 0: counters = [dsconf.params['resource'] for dsconf in dsconfs] log.info( 'Non-zero exit code ({0}) for counters, {1}, on {2}' .format( result.exit_code, counters, dsconf.device)) return # Parse values stdout = parse_stdout(result) if stdout: name, ownergroup, ownernode, state, description = stdout dsconf0 = dsconfs[0] resourceID = 'res-{0}'.format(name) compObject = ObjectMap() compObject.id = prepId(resourceID) compObject.title = name compObject.ownernode = ownernode compObject.description = description compObject.ownergroup = ownergroup compObject.state = state compObject.compname = dsconf0.params['contextcompname'] compObject.modname = dsconf0.params['contextmodname'] compObject.relname = dsconf0.params['contextrelname'] for dsconf in dsconfs: value = (resourceID, state, compObject) timestamp = int(time.mktime(time.localtime())) yield dsconf, value, timestamp else: log.debug('Error in parsing cluster resource data')
def process(self, device, results, log): log.info('Collecting memory and swap for device %s' % device.id) rm = self.relMap() maps = [] for line in results.split("\n"): vals = line.split(':') if len(vals) != 2: continue name, value = vals vals = value.split() if len(vals) != 2: continue value, unit = vals size = int(value) * MULTIPLIER.get(unit, 1) if name == 'MemTotal': maps.append(ObjectMap({"totalMemory": size}, compname="hw")) if name == 'SwapTotal': maps.append(ObjectMap({"totalSwap": size}, compname="os")) return maps
def process(self, device, results, log): log.info('Collecting memory and swap for device %s' % device.id) maps = [] memory_line = "" swap_lines = [] lines = results.split("\n") memory_line = lines[0] swap_lines = results.split("\n")[1:] # Process Memory line memory = memory_line.split(':')[1] mem_value, unit = memory.split() mem_size = int(mem_value) * MULTIPLIER.get(unit, 1) swap_size = 0 # Process Swap Spaces for line in swap_lines: vals = line.split() if len(vals) != 5: continue swapfile, dev, swaplo, blocks, free = vals swap_size += (int(blocks) / 2) maps.append(ObjectMap({"totalMemory": mem_size}, compname="hw")) maps.append(ObjectMap({"totalSwap": swap_size}, compname="os")) return maps
def test_updatedComponent_removeTrue(self): """Test updating a component with _remove or remove set to True.""" for remove_key in ('_remove', 'remove'): eth0_om = ObjectMap({ "id": "eth0", "compname": "os", "relname": "interfaces", remove_key: True, }) changed = self.service.remote_applyDataMaps(self.device.id, [eth0_om]) self.assertFalse( changed, "{} = True resulted in change".format(remove_key)) self.service.remote_applyDataMaps(self.device.id, [ ObjectMap({ "id": "eth0", "compname": "os", "relname": "interfaces", "modname": "Products.ZenModel.IpInterface", "speed": 10e9, })]) changed = self.service.remote_applyDataMaps(self.device.id, [eth0_om]) self.assertTrue( changed, "{} = True didn't result in change".format(remove_key)) self.assertEqual( 0, self.device.os.interfaces.countObjects(), "{} = True didn't remove the component".format(remove_key))
def test_updatedComponent_removeTrue(self): """Test updating a component with _remove or remove set to True.""" for remove_key in ('_remove', 'remove'): DATA = { "id": "eth0", "compname": "os", "relname": "interfaces", remove_key: True, } changed = self.service.applyDataMap(self.device, ObjectMap(DATA)) self.assertFalse(changed, 'update is not idempotent') self.service.applyDataMap( self.device, ObjectMap({ "id": "eth0", "compname": "os", "relname": "interfaces", "modname": "Products.ZenModel.IpInterface", "speed": 10e9, })) self.assertEqual(1, self.device.os.interfaces.countObjects(), 'failed to add object') changed = self.service.applyDataMap(self.device, ObjectMap(DATA)) self.assertTrue(changed, "remove object failed") self.assertEqual(0, self.device.os.interfaces.countObjects(), "failed to remove component")
def process(self, device, results, log): """ Must return one of : - None, changes nothing. Good in error cases. - A RelationshipMap, for the device to component information - An ObjectMap, for the device device information - A list of RelationshipMaps and ObjectMaps, both """ log.debug('Process results: {}'.format(results)) bamboo_data = results.get('bamboo', '') rm = [] if bamboo_data: bamboo_maps = [] om_bamboo = ObjectMap() bamboo_name = 'Bamboo {}'.format(bamboo_data['version']) om_bamboo.id = self.prepId(bamboo_name) om_bamboo.title = bamboo_name bamboo_maps.append(om_bamboo) rm.append(RelationshipMap(relname='bambooServers', modname='ZenPacks.community.Bamboo.BambooServer', compname='', objmaps=bamboo_maps)) log.debug('{}: process maps:{}'.format(device.id, rm)) return rm
def process(self, device, results, log): log.info('Processing VMware ESXi host info for device %s' % device.id) rlines = results.split("\n") for line in rlines: if line.startswith("Warning:"): log.warning('%s' % line) elif re.search(';', line): maps = [] osVendor, osProduct, hwVendor, hwProduct, memorySize, cpuMhz, cpuModel, numCpuCores, numCpuPkgs, numCpuThreads, numNics, esxiHostName, vmotionState = line.split( ';') maps.append( ObjectMap({'totalMemory': memorySize}, compname='hw')) maps.append(ObjectMap({'totalSwap': 0}, compname='os')) om = self.objectMap() om.setOSProductKey = osProduct om.setHWProductKey = hwProduct om.cpuMhz = long(cpuMhz) om.cpuModel = cpuModel om.numCpuCores = int(numCpuCores) om.numCpuPkgs = int(numCpuPkgs) om.numCpuCoresPerPkgs = int(numCpuCores) / int(numCpuPkgs) om.numCpuThreads = int(numCpuThreads) om.numNics = int(numNics) om.esxiHostName = esxiHostName if int(vmotionState) == 0: om.vmotionState = True else: om.vmotionState = False maps.append(om) return maps
def add_maps(self, result, ds): """ Return a list of ObjectMaps with config properties updates for this regionserver and all it's regions. """ oms = [] conf = ConfWrapper(result) oms.append( ObjectMap({ "compname": "hbase_servers/{}".format(self.component), "modname": "Region Server conf", 'handler_count': conf.handler_count, 'memstore_upper_limit': conf.memstore_upper_limit, 'memstore_lower_limit': conf.memstore_lower_limit, 'logflush_interval': conf.logflush_interval })) # All the regions within the region server will have the same # configuration as set in the region server's conf file. for region in ds.region_ids: oms.append( ObjectMap({ "compname": "hbase_servers/{}/regions/{}{}{}".format( ds.component, ds.component, NAME_SPLITTER, prepId(region)), "modname": "Region conf", 'memstore_flush_size': convToUnits(conf.memestore_flush_size), 'max_file_size': convToUnits(conf.max_file_size) })) return oms
def process(self, device, results, log): log.info('Collecting docker containers for device %s' % device.id) # Change results into a list of of results. One element per command. results = results_from_result(results) maps = [] # Map device "docker_version" property. if results[0].startswith("Docker version"): log.info("%s: %s", device.id, results[0]) maps.append(ObjectMap({'docker_version': results[0]})) else: log.info("%s: no docker version", device.id) maps.append(ObjectMap({"docker_version": None})) try: rows = parsing.rows_from_output( results[1], expected_columns=[ "CONTAINER ID", "IMAGE", "COMMAND", "CREATED", "PORTS", "NAMES", ]) except parsing.MissingColumnsError: log.info("%s: unexpected docker ps output", device.id) return maps rm = self.relMap() maps.append(rm) if not rows: log.info("%s: no docker containers found", device.id) return maps try: cgroup_path = parsing.cgroup_path_from_output(results[2]) except parsing.CgroupPathNotFound: log.info("%s: no cgroup path found. The default value '/sys/fs/cgroup' is set", device.id) cgroup_path = "/sys/fs/cgroup" for row in rows: rm.append( self.objectMap({ "id": row["CONTAINER ID"], "title": row["NAMES"], "image": row["IMAGE"], "command": row["COMMAND"], "created": row["CREATED"], "ports": row["PORTS"], "cgroup_path": cgroup_path, })) log.info("%s: found %s Docker containers", device.id, len(rm.maps)) return maps
def base_relmap(self): return RelationshipMap(compname="os", relname="interfaces", modname="Products.ZenModel.IpInterface", objmaps=[ ObjectMap({"id": "eth0"}), ObjectMap({"id": "eth1"}), ])
def objectMap(self, data={}): """Create an object map from the data """ om = ObjectMap(data) om.compname = self.compname om.modname = self.modname om.classname = self.classname return om
def test_updateDevice(self): """Test updating device properties.""" DATA = {"rackSlot": "near-the-top"} changed = self.service.applyDataMap(self.device, ObjectMap(DATA)) self.assertTrue(changed, "update Device failed") self.assertEqual("near-the-top", self.device.rackSlot) changed = self.service.applyDataMap(self.device, ObjectMap(DATA)) self.assertFalse(changed, "updateDevice not idempotent")
def process(self, device, results, log): log.info("Modeler %s processing data for device %s", self.name(), device.id) # Results is a tuple with two items. The first (0) index contains a # dictionary with the results of our "snmpGetMap" queries. The second # (1) index contains a dictionary with the results of our # "snmpGetTableMaps" queries. getdata, tabledata = results # getdata contents.. # {'memTotalReal': 2058776, 'memTotalSwap': 720888} # tabledata contents.. # {'diskIOTable': {'1': {'device': 'ram0', 'index': 1}, # '2': {'device': 'ram1', 'index': 2}, # '3': {'device': 'ram2', 'index': 3}, # '4': {'device': 'ram4', 'index': 4}}} # Create a list to fill up with our results. maps = [] # First we build an ObjectMap to apply to the device's hardware (hw) # component to set the total memory size. Need to check whether SNMP value # suppilied for memTotalReal. If so, multiply the returned value # by 1024 because the SNMP result is in kilybytes and we want to store # it in bytes. if getdata['memTotalReal']: maps.append( ObjectMap({'totalMemory': getdata['memTotalReal'] * 1024}, compname='hw')) # Now do the same thing for total swap space. Zenoss stores this on the # Operating System (os) component of the device. if getdata['memTotalSwap']: maps.append( ObjectMap({'totalSwap': getdata['memTotalSwap'] * 1024}, compname='os')) # Log for each disk returned from our GetTableMap. If we wanted to # create new disks in the model we'd create a RelationshipMap for them # and add an ObjectMap to it for each row in this table. See the # ExampleCMD plugin for an example of this. for snmpindex, disk in tabledata.get('diskIOTable').items(): log.info("Found disk %s", disk['device']) # The process method of the modeler plugin class below is expected to # return output in one of the following forms. # # 1. A single ObjectMap instance # 2. A single RelationshipMap instance # 3. A list of ObjectMap and RelationshipMap instances # 4. None # # If your modeler plugin encounters a bad state and you don't want to # affect Zenoss' model of the device you should return None. return maps
def model_connectors(self, results, log): log.debug('model_connectors data: {}'.format(results)) rings = {} for entry in results: ring = entry['ring'] if ring not in rings: rings[ring] = [] rings[ring].append(entry) rm = [] for ring, connectors in rings.items(): compname = 'scalitySupervisors/Supervisor/scalityRings/{}'.format( ring) connector_maps = [] for connector in connectors: volume_id = connector['id'] om_connector = ObjectMap() om_connector.id = self.prepId(volume_id) om_connector.title = connector['name'] om_connector.connector_id = volume_id om_connector.protocol = connector['protocol'] om_connector.detached = connector['detached'] om_connector.address = connector['address'] om_connector.ring = connector['ring'] connector_maps.append(om_connector) rm.append( RelationshipMap( compname=compname, relname='scalityConnectors', modname='ZenPacks.community.Scality.ScalityConnector', objmaps=connector_maps)) return rm
def test_updateDeviceHW(self): """Test updating device.hw properties.""" DATA = { "compname": "hw", "totalMemory": 45097156608, } changed = self.service.applyDataMap(self.device, ObjectMap(DATA)) self.assertTrue(changed, "device.hw not changed by first ObjectMap") self.assertEqual(45097156608, self.device.hw.totalMemory) changed = self.service.applyDataMap(self.device, ObjectMap(DATA)) self.assertFalse(changed, "update is not idempotent")
def process(self, device, results, log): """Process results. Return iterable of datamaps or None.""" maps = [] pools = [] j_data = json.loads(results) serverdict = {} devicedata = {} for k, v in j_data.iteritems(): if isinstance(v, dict): #got a server pool log.info('Pool %s\n' % (k)) poolName = self.prepId(k) serverdictk = {} for k1, v1 in v.iteritems(): if isinstance(v1, dict): # got a server serverdictk[k1] = v1 else: log.info( 'Server pool attributes - key is %s and value is %s' % (k1, v1)) serverdict[poolName] = serverdictk pools.append( ObjectMap(data={ 'id': poolName, 'title': poolName, })) else: if k in ['version', 'uptime', 'curr_connections']: if k == 'uptime': # uptime in seconds so convert to days v = int(v / 86400) device_attr = 'twemproxy_' + k devicedata[device_attr] = v log.info( 'Twemproxy device attributes - key is %s and value is %s' % (device_attr, v)) maps.append( ObjectMap( modname='ZenPacks.community.zplib.twemproxy.TwemproxyDevice', data=devicedata)) maps.append( RelationshipMap( relname='twemproxyServerPools', modname= 'ZenPacks.community.zplib.twemproxy.TwemproxyServerPool', objmaps=pools)) maps.extend(self.getTwemproxyServerMap(device, serverdict, log)) return maps
def makePVMap(self, columns): # pv_name,pv_fmt,pv_attr,pv_size,pv_free,pv_uuid,vg_name pv_om = ObjectMap() pv_om.title = columns['pv_name'] pv_om.id = 'pv-{}'.format(self.prepId(columns['pv_name'])) pv_om.format = columns['pv_fmt'] pv_om.attributes = self.lvm_parser.pv_attributes(columns['pv_attr']) pv_om.uuid = columns['pv_uuid'] pv_om.set_volumeGroup = 'vg-{}'.format(columns['vg_name']) if columns['vg_name'] else '' pv_om.relname = 'physicalVolumes' pv_om.modname = 'ZenPacks.zenoss.LinuxMonitor.PhysicalVolume' return pv_om
def process(self, device, results, log): log.info("Modeler %s processing data for device %s", self.name(), device.id) if 'neutron.conf' not in results: log.info("No neutron ini files to process.") return data = { 'neutron_core_plugin': None, 'neutron_mechanism_drivers': [], 'neutron_type_drivers': [], 'set_neutron_ini': {} } if 'plugin_names' not in results: log.error("No neutron implementation plugins were identified, unable to continue.") return if results['neutron.conf']: filename = 'neutron.conf' ini = results[filename] data['neutron_core_plugin'] = self.ini_get(device, filename, ini, 'DEFAULT', 'core_plugin', required=True) if data['neutron_core_plugin']: if data['neutron_core_plugin'] in ('neutron.plugins.ml2.plugin.Ml2Plugin', 'ml2'): filename = 'plugins/ml2/ml2_conf.ini' ini = results[filename] if ini: data['neutron_type_drivers'] = split_list(self.ini_get(device, filename, ini, 'ml2', 'type_drivers', required=True)) data['neutron_mechanism_drivers'] = split_list(self.ini_get(device, filename, ini, 'ml2', 'mechanism_drivers', required=True)) for plugin_name in results['plugin_names']: # See if we have any plugins registered for the core module # (if not ML2) or mechanism type (if ML2) plugin = zope.component.queryUtility(INeutronImplementationPlugin, plugin_name) if not plugin: continue log.debug("(Process) Using plugin '%s'" % plugin_name) for filename, section, option in plugin.ini_required(): ini = results.get(filename, None) if ini: data['set_neutron_ini'][(filename, section, option)] = self.ini_get(device, filename, ini, section, option, required=True) for filename, section, option in plugin.ini_optional(): ini = results.get(filename, None) if ini: data['set_neutron_ini'][(filename, section, option)] = self.ini_get(device, filename, ini, section, option) return ObjectMap({'setApplyDataMapToOpenStackInfrastructureEndpoint': ObjectMap(data)})
def process(self, device, results, log): log.info("Modeler %s processing data for device %s", self.name(), device.id) device_om = ObjectMap() device_om.is_iis = False maps = [device_om] rm = self.relMap() if results.get('IIsWebServerSetting'): device_om.is_iis = True for iisSite in results.get('IIsWebServerSetting', ()): om = self.objectMap() om.id = self.prepId(iisSite.Name) if float(self.iis_version) == 6: om.statusname = iisSite.Name else: om.statusname = iisSite.ServerComment om.title = iisSite.ServerComment om.iis_version = self.iis_version om.sitename = iisSite.ServerComment # Default Web Site if hasattr( iisSite, 'AppPoolId'): # ZPS-5407 Can't get DefaultAppPool name om.apppool = iisSite.AppPoolId elif hasattr(iisSite, 'ApplicationPool' ): # ZPS-5407 Can't get DefaultAppPool name om.apppool = iisSite.ApplicationPool for iisVirt in results.get('IIsWebVirtualDirSetting', ()): if (iisVirt.Name == iisSite.Name + "/ROOT") or (iisVirt.Name == iisSite.Name + "/root"): if iisVirt.AppPoolId is not None and iisVirt.AppPoolId != 'None': # ZPS-5407 Can't get DefaultAppPool name om.apppool = iisVirt.AppPoolId rm.append(om) elif results.get('IIs7Site', False): device_om.is_iis = True for iisSite in results.get('IIs7Site', ()): try: om = self.objectMap() om.id = self.prepId(iisSite.Id) om.title = om.statusname = om.sitename = iisSite.Name om.iis_version = self.iis_version om.apppool = iisSite.ApplicationPool rm.append(om) except AttributeError: pass maps.append(rm) return maps
def process(self, device, results, log): """collect snmp information from this device""" import re log.info('processing %s for device %s', self.name(), device.id) getdata, tabledata = results om = self.objectMap(getdata) om.totalSwap = om.totalSwap * 4096 maps = [] if om.totalMemory > 0: maps.append( ObjectMap({"totalMemory": long(om.totalMemory)}, compname="hw")) maps.append(ObjectMap({"totalSwap": om.totalSwap}, compname="os")) return maps
def process(self, device, results, log): """collect snmp information from this device""" log.info('processing %s for device %s', self.name(), device.id) maps = [] for record in results["Win32_OperatingSystem"]: if record.TotalVisibleMemorySize: totalMemory = int(record.TotalVisibleMemorySize) * 1024 maps.append(ObjectMap({"totalMemory": totalMemory}, compname="hw")) if record.TotalVirtualMemorySize: totalSwap = int(record.TotalVirtualMemorySize) * 1024 maps.append(ObjectMap({"totalSwap": totalSwap}, compname="os")) return maps
def model_nodes(self, results, log): log.debug('model_nodes data: {}'.format(results)) rings = {} for entry in results: ring_name = entry['ring'] if ring_name not in rings: rings[ring_name] = [] rings[ring_name].append(entry) rm = [] for ring, nodes in rings.items(): compname = 'scalitySupervisors/Supervisor/scalityRings/{}'.format( ring) node_maps = [] for node in nodes: om_node = ObjectMap() node_name = node['name'] om_node.id = self.prepId('{}_{}'.format(ring, node_name)) om_node.title = node_name om_node.ring = ring # TODO: not safe om_node.admin_endpoint = '{}:{}'.format( node['admin_address'], node['admin_port']) om_node.chord_endpoint = '{}:{}'.format( node['chord_address'], node['chord_port']) om_node.server_endpoint = node['server'] node_maps.append(om_node) rm.append( RelationshipMap( compname=compname, relname='scalityNodes', modname='ZenPacks.community.Scality.ScalityNode', objmaps=node_maps)) return rm
def makeHDMap(self, columns): hd_om = ObjectMap() hd_om.title = columns['device_block'] hd_om.id = 'disk-{}'.format(self.prepId( columns['device_block'].replace(' ', '_'))) hd_om.major_minor = columns['major_minor'] hd_om.mount = columns['mount'] hd_om.size = int(columns['size']) hd_om.relname = 'harddisks' hd_om.modname = 'ZenPacks.zenoss.LinuxMonitor.HardDisk' return hd_om
def process(self, device, results, log): """Collect command-line information from this device""" log.info("Processing the uname -a info for device %s" % device.id) rm = self.relMap() maps = [] output = results.split('\n') maps.append( ObjectMap({"totalMemory": int(output[4].split()[1])}, compname="hw")) maps.append( ObjectMap({"totalSwap": int(output[2].split()[1])}, compname="os")) return maps
def _validate_datamap(device, datamap, relname=None, compname=None, modname=None, parentId=None): if isinstance(datamap, RelationshipMap): log.debug('_validate_datamap: got valid RelationshipMap') elif relname: log.debug('_validate_datamap: build relationship_map using relname') datamap = RelationshipMap(relname=relname, compname=compname, modname=modname, objmaps=datamap, parentId=parentId) elif isinstance(datamap, IncrementalDataMap): log.debug('_validate_datamap: got valid IncrementalDataMap') elif isinstance(datamap, ObjectMap): log.debug('_validate_datamap: got valid ObjectMap') datamap = IncrementalDataMap(device, datamap) else: log.debug('_validate_datamap: build object_map') datamap = ObjectMap(datamap, compname=compname, modname=modname) datamap = IncrementalDataMap(device, datamap) return datamap
def model_s3clusters(self, s3clusters, log): log.debug('model_s3clusters data: {}'.format(s3clusters)) s3cluster_maps = [] for s3cluster in s3clusters: s3cluster_name = s3cluster['name'] om_s3cluster = ObjectMap() om_s3cluster.id = self.prepId(s3cluster_name) om_s3cluster.title = s3cluster_name om_s3cluster.cluster_id = s3cluster['id'] s3cluster_maps.append(om_s3cluster) return RelationshipMap( compname='scalitySupervisors/Supervisor', relname='scalityS3Clusters', modname='ZenPacks.community.Scality.ScalityS3Cluster', objmaps=s3cluster_maps)
def process(self, device, results, log): log.info( "Modeler %s processing data for device %s", self.name(), device.id) device_om = ObjectMap() device_om.is_iis = False maps = [device_om] rm = self.relMap() if results.get('IIsWebServerSetting'): device_om.is_iis = True for iisSite in results.get('IIsWebServerSetting', ()): om = self.objectMap() om.id = self.prepId(iisSite.Name) if float(self.iis_version) == 6: om.statusname = iisSite.Name else: om.statusname = iisSite.ServerComment om.title = iisSite.ServerComment om.iis_version = self.iis_version om.sitename = iisSite.ServerComment # Default Web Site if hasattr(iisSite, 'AppPoolId'): # ZPS-5407 Can't get DefaultAppPool name om.apppool = iisSite.AppPoolId elif hasattr(iisSite, 'ApplicationPool'): # ZPS-5407 Can't get DefaultAppPool name om.apppool = iisSite.ApplicationPool for iisVirt in results.get('IIsWebVirtualDirSetting', ()): if (iisVirt.Name == iisSite.Name + "/ROOT") or (iisVirt.Name == iisSite.Name + "/root"): if iisVirt.AppPoolId is not None and iisVirt.AppPoolId != 'None': # ZPS-5407 Can't get DefaultAppPool name om.apppool = iisVirt.AppPoolId rm.append(om) elif results.get('IIs7Site', False): device_om.is_iis = True for iisSite in results.get('IIs7Site', ()): try: om = self.objectMap() om.id = self.prepId(iisSite.Id) om.title = om.statusname = om.sitename = iisSite.Name om.iis_version = self.iis_version om.apppool = iisSite.ApplicationPool rm.append(om) except AttributeError: pass maps.append(rm) return maps
def makeVGMap(self, columns): # vg_name,vg_attr,vg_size,vg_free,vg_uuid vg_om = ObjectMap() vg_om.title = columns['vg_name'] vg_om.id = 'vg-{}'.format(self.prepId(columns['vg_name'])) vg_om.attributes = self.lvm_parser.vg_attributes(columns['vg_attr']) vg_om.uuid = columns['vg_uuid'] vg_om.relname = 'volumeGroups' vg_om.modname = 'ZenPacks.zenoss.LinuxMonitor.VolumeGroup' return vg_om
def parse_result(self, dsconfs, result): if result.exit_code != 0: counters = [dsconf.params['resource'] for dsconf in dsconfs] log.info( 'Non-zero exit code ({0}) for counters, {1}, on {2}' .format( result.exit_code, counters, dsconf.device)) return # Parse values stdout = parse_stdout(result) if stdout: status, name = stdout dsconf0 = dsconfs[0] compObject = ObjectMap() compObject.id = dsconf0.params['instanceid'] compObject.title = dsconf0.params['instancename'] compObject.compname = dsconf0.params['contextcompname'] compObject.modname = dsconf0.params['contextmodname'] compObject.relname = dsconf0.params['contextrelname'] for dsconf in dsconfs: value = ( dsconf0.params['instanceid'], status.strip(), compObject ) yield dsconf, value else: log.debug('Error in parsing mssql instance data')
def get_backup_om(self, om_instance, instance, stdout_line): backupobj = stdout_line backup = backupobj.split('\t') backupdict = {} for backupitem in backup: key, value = backupitem.split('---') backupdict[key.lower()] = value.strip() if ('name' in backupdict): om_backup = ObjectMap() om_backup.id = self.prepId(instance + backupdict['name']) om_backup.title = backupdict['name'] om_backup.devicetype = backupdict['devicetype'] om_backup.physicallocation = backupdict['physicallocation'] om_backup.status = backupdict['status'] om_backup.instancename = om_instance.id return om_backup
def process(self, device, results, log): """collect CIM information from this device""" log.info("processing %s for device %s", self.name(), device.id) maps = [] rm = self.relMap() instances = results.get("CIM_Chassis") if not instances: return rm sysnames = self._getSysnames(device, results, "CIM_Chassis") sysname = sysnames[0] for inst in instances: if (inst.get("_sysname") or "").lower() not in sysnames: continue try: layout = self._getLayout(results, inst) manuf = inst.get("_manuf") or "Unknown" productKey = inst.get("setProductKey") or "" if not maps and self._isSystemChassis(results, sysname, inst): if not inst: continue om = ObjectMap() if productKey or (manuf != "Unknown"): om.setHWProductKey = MultiArgs(productKey, manuf) serialNumber = inst.get("serialNumber") or "" if serialNumber: om.setHWSerialNumber = serialNumber tag = inst.get("tag") or inst.get("id") or "" if tag: if tag.startswith(serialNumber) and tag != serialNumber: tag = tag[len(serialNumber):] om.setHWTag = tag maps.append(om) continue self._setCimStatusName(inst) om = self.objectMap(inst) om.id = self.prepId(om.id) if not om.id: continue if productKey or (manuf != "Unknown"): om.setProductKey = MultiArgs(productKey, manuf) if layout: om.layout = layout except AttributeError: continue rm.append(om) maps.append(rm) return maps
def _new_objmap(self, objmap): # Create a new empty objmap based on the suppied one, with all # structural properties carried over, but no data, no _add, and no # _remove. new_objmap = ObjectMap() if objmap.modname: new_objmap.modname = objmap.modname if objmap.compname: new_objmap.compname = objmap.compname if objmap.classname: new_objmap.classname = objmap.classname if hasattr(objmap, 'relname'): new_objmap.relname = objmap.relname if hasattr(objmap, 'id'): new_objmap.id = objmap.id return new_objmap
def collect(self, device, log): # Check if the device is a cluster device. isCluster = True if 'Microsoft/Cluster' in device.getDeviceClassName \ else False dbinstance = prepare_zDBInstances(device.zDBInstances) username = device.windows_user password = device.windows_password dblogins = {} eventmessage = 'Error parsing zDBInstances' try: dbinstance = json.loads(dbinstance) users = [el.get('user') for el in filter(None, dbinstance)] if ''.join(users): for el in filter(None, dbinstance): dblogins[el.get('instance')] = dict( username=el.get('user') if el.get('user') else username, password=el.get('passwd') if el.get('passwd') else password, login_as_user=False if el.get('user') else True ) else: for el in filter(None, dbinstance): dblogins[el.get('instance')] = dict( username=username, password=password, login_as_user=True ) results = {'clear': eventmessage} except (ValueError, TypeError, IndexError): # Error with dbinstance names or password results = {'error': eventmessage} defer.returnValue(results) conn_info = self.conn_info(device) winrs = SQLCommander(conn_info) dbinstances = winrs.get_instances_names(isCluster) instances = yield dbinstances maps = {} instance_oms = [] database_oms = [] backup_oms = [] jobs_oms = [] server_config = {} sqlhostname = '' for serverconfig in instances.stdout: key, value = serverconfig.split(':', 1) serverlist = [] if not value: continue if key in server_config: serverlist = server_config[key] serverlist.append(value.strip()) server_config[key] = serverlist else: serverlist.append(value.strip()) server_config[key] = serverlist if not server_config.get('instances'): eventmessage = 'No MSSQL Servers are installed but modeler is enabled' results = {'error': eventmessage} defer.returnValue(results) sqlhostname = server_config['hostname'][0] # Set value for device sqlhostname property device_om = ObjectMap() device_om.sqlhostname = sqlhostname for instance in server_config['instances']: #clear_inst = prepare_instance(instance) owner_node = '' # Leave empty for local databases. # For cluster device, create a new a connection to each node, # which owns network instances. if isCluster: try: owner_node, sql_server, instance = instance.split('\\') device.windows_servername = owner_node.strip() conn_info = self.conn_info(device) winrs = SQLCommander(conn_info) except ValueError: log.error('Owner node for DB Instance {0} was not found'.format( instance)) continue if instance not in dblogins: log.info("DB Instance {0} found but was not set in zDBInstances. " \ "Using default credentials.".format(instance)) instance_title = instance if instance == 'MSSQLSERVER': instance_title = sqlserver = sqlhostname else: sqlserver = '{0}\{1}'.format(sqlhostname, instance) if isCluster: if instance == 'MSSQLSERVER': instance_title = sqlserver = sql_server.strip() else: sqlserver = '{0}\{1}'.format(sql_server.strip(), instance) om_instance = ObjectMap() om_instance.id = self.prepId(instance_title) om_instance.title = instance_title om_instance.instancename = instance_title om_instance.cluster_node_server = '{0}//{1}'.format( owner_node.strip(), sqlserver) instance_oms.append(om_instance) sqlConnection = [] # Look for specific instance creds first try: sqlusername = dblogins[instance]['username'] sqlpassword = dblogins[instance]['password'] login_as_user = dblogins[instance]['login_as_user'] except KeyError: # Try default MSSQLSERVER creds try: sqlusername = dblogins['MSSQLSERVER']['username'] sqlpassword = dblogins['MSSQLSERVER']['password'] login_as_user = dblogins['MSSQLSERVER']['login_as_user'] except KeyError: # Use windows auth sqlusername = username sqlpassword = password login_as_user = True # DB Connection Object sqlConnection.append("$con = new-object " \ "('Microsoft.SqlServer.Management.Common.ServerConnection')" \ "'{0}', '{1}', '{2}';".format(sqlserver, sqlusername, sqlpassword)) if login_as_user: log.debug("Windows auth %s / %s" % (sqlusername, sqlpassword)) # Login using windows credentials sqlConnection.append("$con.LoginSecure=$true;") sqlConnection.append("$con.ConnectAsUser=$true;") # Omit domain part of username sqlConnection.append("$con.ConnectAsUserName='******';".format(sqlusername.split("\\")[-1])) sqlConnection.append("$con.ConnectAsUserPassword='******';".format(sqlpassword)) else: log.debug("DB auth %s / %s" % (sqlusername, sqlpassword)) sqlConnection.append("$con.Connect();") # Connect to Database Server sqlConnection.append("$server = new-object " \ "('Microsoft.SqlServer.Management.Smo.Server') $con;") db_sqlConnection = [] # Get database information db_sqlConnection.append('write-host "====Databases";') db_sqlConnection.append('$server.Databases | foreach {' \ 'write-host \"Name---\" $_,' \ '\"`tVersion---\" $_.Version,' \ '\"`tIsAccessible---\" $_.IsAccessible,' \ '\"`tID---\" $_.ID,' \ '\"`tOwner---\" $_.Owner,' \ '\"`tLastBackupDate---\" $_.LastBackupDate,'\ '\"`tCollation---\" $_.Collation,'\ '\"`tCreateDate---\" $_.CreateDate,'\ '\"`tDefaultFileGroup---\" $_.DefaultFileGroup,'\ '\"`tPrimaryFilePath---\" $_.PrimaryFilePath,'\ '\"`tLastLogBackupDate---\" $_.LastLogBackupDate,' \ '\"`tSystemObject---\" $_.IsSystemObject,' \ '\"`tRecoveryModel---\" $_.DatabaseOptions.RecoveryModel' \ '};') # Get SQL Backup Jobs information backup_sqlConnection = [] backup_sqlConnection.append('write-host "====Backups";') # Get database information backup_sqlConnection.append('$server.BackupDevices | foreach {' \ 'write-host \"Name---\" $_.Name,' \ '\"`tDeviceType---\" $_.BackupDeviceType,' \ '\"`tPhysicalLocation---\" $_.PhysicalLocation,' \ '\"`tStatus---\" $_.State' \ '};') # Get SQL Jobs information jobsquery = ( "select s.name as jobname, s.job_id as jobid, " "s.enabled as enabled, s.date_created as datecreated, " # Replace each new line with a space in description. "replace(replace(s.description, char(13), char(32)), " "char(10), char(32)) as description, " "l.name as username from msdb..sysjobs s left join " "master.sys.syslogins l on s.owner_sid = l.sid" ) job_sqlConnection = [] job_sqlConnection.append('write-host "====Jobs";') job_sqlConnection.append("$db = $server.Databases[0];") job_sqlConnection.append("$ds = $db.ExecuteWithResults('{0}');".format(jobsquery)) job_sqlConnection.append('$ds.Tables | Format-List;') instance_info = yield winrs.run_command( ''.join(getSQLAssembly() + sqlConnection + db_sqlConnection + \ backup_sqlConnection + job_sqlConnection) ) log.debug('Modeling databases, backups, jobs results: {}'.format(instance_info)) check_username(instance_info, instance, log) in_databases=False in_backups = False in_jobs = False for stdout_line in filter_sql_stdout(instance_info.stdout): if stdout_line == 'assembly load error': break if stdout_line == '====Databases': in_databases = True in_backups = False in_jobs = False continue elif stdout_line == '====Backups': in_databases = False in_backups = True in_jobs = False continue elif stdout_line == '====Jobs': in_databases = False in_backups = False in_jobs = True continue if in_databases: dbobj = stdout_line #for dbobj in filter_sql_stdout(databases.stdout): db = dbobj.split('\t') dbdict = {} for dbitem in db: try: key, value = dbitem.split('---') dbdict[key.lower()] = value.strip() except (ValueError): log.info('Error parsing returned values : {0}'.format( dbitem)) lastlogbackupdate = None if ('lastlogbackupdate' in dbdict) \ and (dbdict['lastlogbackupdate'][:8] != '1/1/0001'): lastlogbackupdate = dbdict['lastlogbackupdate'] lastbackupdate = None if ('lastbackupdate' in dbdict) \ and (dbdict['lastbackupdate'][:8] != '1/1/0001'): lastbackupdate = dbdict['lastbackupdate'] if ('id' in dbdict): om_database = ObjectMap() om_database.id = self.prepId(instance + dbdict['id']) om_database.title = dbdict['name'][1:-1] om_database.instancename = om_instance.id om_database.version = dbdict['version'] om_database.owner = dbdict['owner'] om_database.lastbackupdate = lastbackupdate om_database.lastlogbackupdate = lastlogbackupdate om_database.isaccessible = dbdict['isaccessible'] om_database.collation = dbdict['collation'] om_database.createdate = str(dbdict['createdate']) om_database.defaultfilegroup = dbdict['defaultfilegroup'] om_database.primaryfilepath = dbdict['primaryfilepath'] om_database.cluster_node_server = '{0}//{1}'.format( owner_node.strip(), sqlserver) om_database.systemobject = dbdict['systemobject'] om_database.recoverymodel = dbdict['recoverymodel'] om_database.status= 'Up' if dbdict['isaccessible'] == 'True' else 'Down' database_oms.append(om_database) elif in_backups: backupobj = stdout_line backup = backupobj.split('\t') backupdict = {} for backupitem in backup: key, value = backupitem.split('---') backupdict[key.lower()] = value.strip() om_backup = ObjectMap() om_backup.id = self.prepId(instance + backupdict['name']) om_backup.title = backupdict['name'] om_backup.devicetype = backupdict['devicetype'] om_backup.physicallocation = backupdict['physicallocation'] om_backup.status = backupdict['status'] om_backup.instancename = om_instance.id backup_oms.append(om_backup) elif in_jobs: job = stdout_line # Make sure that the job description length does not go # beyond the buffer size (4096 characters). if ':' not in job: continue key, value = job.split(':', 1) if key.strip() == 'jobname': #New Job Record om_jobs = ObjectMap() om_jobs.instancename = om_instance.id om_jobs.title = value.strip() om_jobs.cluster_node_server = '{0}//{1}'.format( owner_node.strip(), sqlserver) else: if key.strip() == 'jobid': om_jobs.jobid = value.strip() om_jobs.id = self.prepId(om_jobs.jobid) elif key.strip() == 'enabled': om_jobs.enabled = 'Yes'\ if value.strip() == '1' else 'No' elif key.strip() == 'description': om_jobs.description = value.strip() elif key.strip() == 'datecreated': om_jobs.datecreated = str(value) elif key.strip() == 'username': om_jobs.username = value.strip() jobs_oms.append(om_jobs) maps['clear'] = eventmessage maps['databases'] = database_oms maps['instances'] = instance_oms maps['backups'] = backup_oms maps['jobs'] = jobs_oms maps['device'] = device_om defer.returnValue(maps)
def process(self, device, results, log): # call self.relMap() helper method that initializes relname and compname for me # rm = self.relMap() lines = results.split('\n') if lines[0] != "yes": # we are not in a container or on a host return [] pos = 1 try: page_size = int(lines[pos]) except ValueError: page_size = 4096 pos += 1 arch = lines[pos] pos += 1 hw_map = ObjectMap({"page_size" : page_size, "arch" : arch }, compname="hw") infolines = [] while lines[pos] != "#veinfo-stop": infolines.append(lines[pos]) pos += 1 vzinfo = VZInfoParser.parse(infolines) # if we find VE 0, we are on a host... foundZero = False # blank line: pos += 2 while pos < len(lines): # helper method - will set compname, modname, and classname for me: # it gets these settings from relname, modname, and classname = modname om = self.objectMap() if lines[pos] == "0": foundZero = True om.title = "CT0" om.id = "0" om.description = "Hardware Node" om.onboot = False om.ve_root = "N/A" om.ve_private = "N/A" om.container_status = "running" om.ostemplate = "N/A" om.ipaddrs=[] om.macaddrs=[] else: om.id = self.prepId(lines[pos]) # NAME if lines[pos+1]: om.title = lines[pos+1] om.hostname = lines[pos+2] om.ostemplate = lines[pos+3] # veth macaddr info on lines[pos+5] om.description = lines[pos+6] om.ve_root = lines[pos+7] om.ve_private = lines[pos+8] om.onboot = False if lines[pos] in vzinfo: om.container_status = vzinfo[lines[pos]] if om.container_status == "running": om.ipaddrs = [] # only update IPs if running so the IPs stick around if the container is stopped during remodel, # so we still have IPs for container component <-> managed device correlation :) for ip in lines[pos+4].split(): om.ipaddrs.append(ip) # again, only update MAC addresses from veth when we are in a running state, so we cache old # ones for correlation if a container happens to be stopped... om.macaddrs = [] for netif in lines[pos+5].split(";"): keypairs = netif.split(",") for kp in keypairs: kv = kp.split("=") if len(kv) != 2: continue if kv[0] == "mac": om.macaddrs.append(kv[1].lower()) if lines[pos+9] == "yes": om.onboot = True pos += 11 rm.append(om) if not foundZero: return [] # a relMap() is just a container to store objectMaps # in relmap and objectmap, there is a compname and modname # any # # # objectmaps and relmaps are temporary objects that the modeler plugin sends to zenhub, which then determines # if the model needs to be updated. # device/containers/106 # om ^ relmap ^ om^ # we are allowd to return: # a relmap - will be filled with object maps that are related to "device" # an objectmap - # a list of relmaps, objectmaps # If we get here, we've identified this as an OpenVZ host. Create a new # ObjectMap that will be applied to the device. Use it to call our # setOpenVZHostTemplate method on the device to bind the host-level # monitoring template. device_map = ObjectMap() device_map.setOpenVZHostTemplate = True return [device_map, hw_map, rm]
def olsonInterface(self, manageIp, macaddr): om = ObjectMap({}, compname = "os", modname = "Products.ZenModel.IpInterface") om.id = self.prepId("eth0") om.title = om.id om.interfaceName = om.id om.description = "Manually Kludged" om.type = "manual" om.speed = 10000000 om.mtu = 1500 om.ifindex = "1" om.adminStatus = 1 om.operStatus = 1 om.monitor = False om.setIpAddresses = [manageIp, ] om.macaddress = macaddr # om.lockFromDeletion() # om.lockFromUpdates() return RelationshipMap(relname = "interfaces", compname = "os", modname = "Products.ZenModel.IpInterface", objmaps = [om,])
def makeLVMap(self, columns): # lv_name,vg_name,lv_attr,lv_size,lv_uuid,origin lv_om = ObjectMap() lv_om.title = columns['lv_name'] lv_om.vgname = columns['vg_name'] lv_om.id = 'lv-{}'.format(self.prepId(columns['vg_name'])+'_'+self.prepId(columns['lv_name'])) lv_om.attributes = self.lvm_parser.lv_attributes(columns['lv_attr']) lv_om.lvsize = int(columns['lv_size']) lv_om.uuid = columns['lv_uuid'] if columns['origin']: lv_om.origin = columns['origin'] lv_om.relname = 'snapshotVolumes' lv_om.modname = 'ZenPacks.zenoss.LinuxMonitor.SnapshotVolume' elif columns['lv_metadata_size']: lv_om.id = 'tp-{}'.format(self.prepId(columns['vg_name'])+'_'+self.prepId(columns['lv_name'])) lv_om.metadatasize = int(columns['lv_metadata_size']) lv_om.relname = 'thinPools' lv_om.modname = 'ZenPacks.zenoss.LinuxMonitor.ThinPool' else: lv_om.set_thinPool = None if columns['pool_lv']: lv_om.set_thinPool = 'tp-{}'.format(self.prepId(columns['vg_name'])+'_'+self.prepId(columns['pool_lv'])) lv_om.relname = 'logicalVolumes' lv_om.modname = 'ZenPacks.zenoss.LinuxMonitor.LogicalVolume' return lv_om
def collect(self, device, log): # Sample data for zDBInstanceLogin # MSSQLSERVER;ZenossInstance2 # Sample data for zDBInstancePassword # sa:Sup3rPa$$;sa:WRAAgf4234@#$ dbinstance = device.zDBInstances dbinstancepassword = device.zDBInstancesPassword password = device.zWinRMPassword dblogins = {} eventmessage = 'Error parsing zDBInstances or zDBInstancesPassword' try: if len(dbinstance) > 0 and len(dbinstancepassword) > 0: arrInstance = dbinstance.split(';') arrPassword = dbinstancepassword.split(';') i = 0 for instance in arrInstance: dbuser, dbpass = arrPassword[i].split(':', 1) i = i + 1 dblogins[instance] = {'username': dbuser, 'password': dbpass} else: arrInstance = dbinstance.split(';') for instance in arrInstance: dblogins[instance] = {'username': '******', 'password': password} results = {'clear': eventmessage} except (IndexError, ValueError): # Error with dbinstance names or password results = {'error': eventmessage} defer.returnValue(results) conn_info = self.conn_info(device) winrs = create_single_shot_command(conn_info) #sqlserver = 'SQL1\ZENOSSINSTANCE2' #sqlusername = '******' #sqlpassword = '******' # Base command line setup for powershell pscommand = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " psInstances = [] psInstances.append("$hostname=hostname;") # Get registry key for instances # 32/64 Bit 2008 psInstances.append("if (get-itemproperty \'HKLM:\Software\Wow6432Node\Microsoft\Microsoft SQL Server\')") psInstances.append("{$instances = get-itemproperty \'HKLM:\Software\Wow6432Node\Microsoft\Microsoft SQL Server\';}") # 2003 psInstances.append("if (get-itemproperty \'HKLM:\Software\Microsoft\Microsoft SQL Server\')") psInstances.append("{$instances = get-itemproperty \'HKLM:\Software\Microsoft\Microsoft SQL Server\';}") psInstances.append("$instances.InstalledInstances | foreach {write-host \"instances:\"$_};") psInstances.append("write-host \"hostname:\"$hostname;") command = "{0} \"& {{{1}}}\"".format( pscommand, ''.join(psInstances)) dbinstances = winrs.run_command(command) instances = yield dbinstances maps = {} instance_oms = [] database_oms = [] backup_oms = [] jobs_oms = [] server_config = {} sqlhostname = '' for serverconfig in instances.stdout: key, value = serverconfig.split(':', 1) serverlist = [] if key in server_config: serverlist = server_config[key] serverlist.append(value.strip()) server_config[key] = serverlist else: serverlist.append(value.strip()) server_config[key] = serverlist if server_config['instances'][0] == '': eventmessage = 'No MSSQL Servers are installed but modeler is enabled' results = {'error': eventmessage} defer.returnValue(results) sqlhostname = server_config['hostname'][0] for instance in server_config['instances']: if instance not in dblogins: log.info("DB Instance {0} found but was not set in zDBInstances".format( instance)) continue om_instance = ObjectMap() om_instance.id = self.prepId(instance) om_instance.title = instance om_instance.instancename = instance instance_oms.append(om_instance) if instance in dblogins: sqlConnection = [] if instance == 'MSSQLSERVER': sqlserver = sqlhostname else: sqlserver = '{0}\{1}'.format(sqlhostname, instance) sqlusername = dblogins[instance]['username'] sqlpassword = dblogins[instance]['password'] # DB Connection Object sqlConnection.append("$con = new-object " \ "('Microsoft.SqlServer.Management.Common.ServerConnection')" \ "'{0}', '{1}', '{2}';".format(sqlserver, sqlusername, sqlpassword)) sqlConnection.append("$con.Connect();") # Connect to Database Server sqlConnection.append("$server = new-object " \ "('Microsoft.SqlServer.Management.Smo.Server') $con;") db_sqlConnection = [] # Get database information db_sqlConnection.append('$server.Databases | foreach {' \ 'write-host \"Name---\" $_,' \ '\"`tVersion---\" $_.Version,' \ '\"`tIsAccessible---\" $_.IsAccessible,' \ '\"`tID---\" $_.ID,' \ '\"`tOwner---\" $_.Owner,' \ '\"`tLastBackupDate---\" $_.LastBackupDate,'\ '\"`tCollation---\" $_.Collation,'\ '\"`tCreateDate---\" $_.CreateDate,'\ '\"`tDefaultFileGroup---\" $_.DefaultFileGroup,'\ '\"`tPrimaryFilePath---\" $_.PrimaryFilePath,'\ '\"`tLastLogBackupDate---\" $_.LastLogBackupDate' \ '};') command = "{0} \"& {{{1}}}\"".format( pscommand, ''.join(getSQLAssembly() + sqlConnection + db_sqlConnection)) instancedatabases = winrs.run_command(command) databases = yield instancedatabases for dbobj in databases.stdout: db = dbobj.split('\t') dbdict = {} for dbitem in db: try: key, value = dbitem.split('---') dbdict[key.lower()] = value.strip() except (ValueError): log.info('Error parsing returned values : {0}'.format( dbitem)) if dbdict['lastlogbackupdate'][:8] == '1/1/0001': lastlogbackupdate = None else: lastlogbackupdate = dbdict['lastlogbackupdate'] if dbdict['lastbackupdate'][:8] == '1/1/0001': lastbackupdate = None else: lastbackupdate = dbdict['lastbackupdate'] om_database = ObjectMap() om_database.id = self.prepId(instance + dbdict['id']) om_database.title = dbdict['name'][1:-1] om_database.instancename = om_instance.id om_database.version = dbdict['version'] om_database.owner = dbdict['owner'] om_database.lastbackupdate = lastbackupdate om_database.lastlogbackupdate = lastlogbackupdate om_database.isaccessible = dbdict['isaccessible'] om_database.collation = dbdict['collation'] om_database.createdate = str(dbdict['createdate']) om_database.defaultfilegroup = dbdict['defaultfilegroup'] om_database.primaryfilepath = dbdict['primaryfilepath'] database_oms.append(om_database) # Get SQL Backup Jobs information backup_sqlConnection = [] # Get database information backup_sqlConnection.append('$server.BackupDevices | foreach {' \ 'write-host \"Name---\" $_.Name,' \ '\"`tDeviceType---\" $_.BackupDeviceType,' \ '\"`tPhysicalLocation---\" $_.PhysicalLocation,' \ '\"`tStatus---\" $_.State' \ '};') command = "{0} \"& {{{1}}}\"".format( pscommand, ''.join(getSQLAssembly() + sqlConnection + backup_sqlConnection)) backuplist = winrs.run_command(command) backups = yield backuplist for backupobj in backups.stdout: backup = backupobj.split('\t') backupdict = {} for backupitem in backup: key, value = backupitem.split('---') backupdict[key.lower()] = value.strip() om_backup = ObjectMap() om_backup.id = self.prepId(instance + backupdict['name']) om_backup.title = backupdict['name'] om_backup.devicetype = backupdict['devicetype'] om_backup.physicallocation = backupdict['physicallocation'] om_backup.status = backupdict['status'] om_backup.instancename = om_instance.id backup_oms.append(om_backup) # Get SQL Jobs information jobsquery = "select s.name as jobname, s.job_id as jobid, " \ "s.enabled as enabled, s.date_created as datecreated, " \ "s.description as description, l.name as username from " \ "msdb..sysjobs s left join master.sys.syslogins l on s.owner_sid = l.sid" job_sqlConnection = [] job_sqlConnection.append("$db = $server.Databases[0];") job_sqlConnection.append("$ds = $db.ExecuteWithResults('{0}');".format(jobsquery)) job_sqlConnection.append('$ds.Tables | Format-List;') command = "{0} \"& {{{1}}}\"".format( pscommand, ''.join(getSQLAssembly() + sqlConnection + job_sqlConnection)) jobslist = winrs.run_command(command) jobs = yield jobslist for job in jobs.stdout: key, value = job.split(':', 1) if key.strip() == 'jobname': #New Job Record om_jobs = ObjectMap() om_jobs.instancename = om_instance.id om_jobs.title = value.strip() else: if key.strip() == 'jobid': om_jobs.jobid = value.strip() om_jobs.id = self.prepId(om_jobs.jobid) elif key.strip() == 'enabled': om_jobs.enabled = value.strip() elif key.strip() == 'description': om_jobs.description = value.strip() elif key.strip() == 'datecreated': om_jobs.datecreated = str(value) elif key.strip() == 'username': om_jobs.username = value.strip() jobs_oms.append(om_jobs) maps['clear'] = eventmessage maps['databases'] = database_oms maps['instances'] = instance_oms maps['backups'] = backup_oms maps['jobs'] = jobs_oms defer.returnValue(maps)
def process(self, device, results, log): log.info( "Modeler %s processing data for device %s", self.name(), device.id) sysEnclosure = results.get('Win32_SystemEnclosure', (None,))[0] computerSystem = results.get('Win32_ComputerSystem', (None,))[0] operatingSystem = results.get('Win32_OperatingSystem', (None,))[0] clusterInformation = results.get('MSCluster', ()) exchange_version = results.get('exchange_version') if exchange_version: exchange_version = exchange_version.stdout[0][:2] if exchange_version.stdout else None if exchange_version: exchange_version = {'6': '2003', '8': '2010', '08': '2010', '14': '2010', '15': '2013'}.get( exchange_version ) maps = [] # Device Map device_om = ObjectMap() device_om.snmpSysName = computerSystem.Name device_om.snmpContact = computerSystem.PrimaryOwnerName device_om.snmpDescr = computerSystem.Caption # http://office.microsoft.com/en-001/outlook-help/determine-the-version-of-microsoft-exchange-server-my-account-connects-to-HA010117038.aspx if exchange_version: device_om.msexchangeversion = 'MSExchange%sIS' % (exchange_version if exchange_version in ['2010', '2013'] else "") else: device_om.msexchangeversion = 'MSExchangeIS' # Cluster Information try: clusterlist = [] for cluster in clusterInformation: clusterlist.append(cluster.Name + '.' + computerSystem.Domain) device_om.setClusterMachines = clusterlist except (AttributeError): pass maps.append(device_om) # Hardware Map hw_om = ObjectMap(compname='hw') hw_om.serialNumber = sysEnclosure.SerialNumber hw_om.tag = sysEnclosure.Tag hw_om.setProductKey = MultiArgs( computerSystem.Model, computerSystem.Manufacturer) if hasattr(operatingSystem, 'TotalVisibleMemorySize'): hw_om.totalMemory = 1024 * int(operatingSystem.TotalVisibleMemorySize) else: log.warn( "Win32_OperatingSystem query did not respond with " "TotalVisibleMemorySize: {0}" .format(pformat(sorted(vars(operatingSystem).keys())))) maps.append(hw_om) # Operating System Map os_om = ObjectMap(compname='os') os_om.totalSwap = int(operatingSystem.TotalVirtualMemorySize) * 1024 operatingSystem.Caption = re.sub( r'\s*\S*Microsoft\S*\s*', '', operatingSystem.Caption) osCaption = '{} - {}'.format( operatingSystem.Caption, operatingSystem.CSDVersion) os_om.setProductKey = MultiArgs( osCaption, operatingSystem.Manufacturer) maps.append(os_om) return maps
def get_job_om(self, device, sqlserver, om_instance, owner_node, stdout_line): jobobj = stdout_line # Make sure that the job description length does not go # beyond the buffer size (4096 characters). job_properties = ( 'job_username', 'job_datecreated', 'job_description', 'job_jobid', 'job_enabled', 'job_jobname') jobdict = {} prev_index = len(jobobj) for prop in job_properties: start = jobobj.index(prop) jobitem = jobobj[start:prev_index] prev_index = start key, value = jobitem.split('---', 1) jobdict[key.lower()] = value.strip() om_job = ObjectMap() om_job.instancename = om_instance.id om_job.title = jobdict['job_jobname'] om_job.cluster_node_server = '{0}//{1}'.format( owner_node, sqlserver) om_job.jobid = jobdict['job_jobid'] om_job.id = self.prepId(om_job.jobid) om_job.enabled = 'Yes' if jobdict['job_enabled'] == 'True' else 'No' om_job.description = jobdict['job_description'] om_job.datecreated = str(jobdict['job_datecreated']) om_job.username = jobdict['job_username'] if not om_job.jobid: if not om_job.title: self.log.debug('Skipping job with no title or id on {}.'.format(device.id)) return None om_job.jobid = self.prepId('sqljob_{}_{}'.format(om_job.instancename, om_job.title)) return om_job
def process(self, device, results, log): log.info('Modeler %s processing data for device %s', self.name(), device.id) maps = [] map_resources_oms = [] map_nodes_oms = [] map_networks_oms = [] ownergroups = {} map_apps_to_resource = {} node_ownergroups = {} map_disks_to_node = {} map_interfaces_to_node = {} nodes = results['nodes'] cs_om = ObjectMap() cs_om.setClusterHostMachines = nodes maps.append(cs_om) # Cluster Resource Maps res_spliter_index = results['resources'].index("====") resources = results['resources'][:res_spliter_index] applications = results['resources'][res_spliter_index+1:] # This section is for ClusterService class for resource in resources: resourceline = resource.split("|") res_om = ObjectMap() res_om.id = self.prepId(resourceline[5]) res_om.title = resourceline[0] res_om.coregroup = resourceline[1] res_om.ownernode = resourceline[2] res_om.description = resourceline[4] res_om.priority = resourceline[6] res_om.domain = results['domain'] if res_om.title not in ownergroups: ownergroups[res_om.title] = res_om.id map_resources_oms.append(res_om) # Cluster Application and Services # This section is for ClusterResrouce class for app in applications: appline = app.split("|") app_ownergroup = appline[1] if app_ownergroup in ownergroups: app_om = ObjectMap() app_om.id = self.prepId('res-{0}'.format(appline[0])) app_om.title = appline[0] app_om.ownernode = appline[2] app_om.description = appline[4] app_om.ownergroup = app_ownergroup app_om.domain = results['domain'] groupid = ownergroups[app_om.ownergroup] appsom = [] if groupid in map_apps_to_resource: appsom = map_apps_to_resource[groupid] appsom.append(app_om) map_apps_to_resource[groupid] = appsom # Fixes ZEN-23142 # Remove ClusterServices without any associated ClusterResources configured for m in map_resources_oms: if m.id not in map_apps_to_resource.keys(): map_resources_oms.remove(m) maps.append(RelationshipMap( compname="os", relname="clusterservices", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterService", objmaps=map_resources_oms )) for resourceid, apps in map_apps_to_resource.items(): maps.append(RelationshipMap( compname="os/clusterservices/" + resourceid, relname="clusterresources", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterResource", objmaps=apps )) # This section is for ClusterNode class nodes_data = results['nodes_data'] for node in nodes_data: nodeline = node.split("|") node_om = ObjectMap() node_om.id = self.prepId('node-{0}'.format(nodeline[3])) node_om.title = nodeline[0] node_om.ownernode = nodeline[0] node_om.assignedvote = nodeline[1] node_om.currentvote = nodeline[2] node_om.domain = results['domain'] if node_om.title not in node_ownergroups: node_ownergroups[node_om.title] = node_om.id map_nodes_oms.append(node_om) # This section is for ClusterDisk class clusterdisk = results['clusterdisk'] for disk in clusterdisk: diskline = disk.split("|") disk_ownernode = diskline[3] if disk_ownernode in node_ownergroups: disk_om = ObjectMap() disk_om.id = self.prepId(diskline[0]) disk_om.title = diskline[1] disk_om.volumepath = diskline[2] disk_om.ownernode = disk_ownernode disk_om.disknumber = diskline[4] disk_om.partitionnumber = diskline[5] disk_om.size = sizeof_fmt(diskline[6]) disk_om.freespace = sizeof_fmt(diskline[7]) disk_om.assignedto = diskline[9] disk_om.domain = results['domain'] nodeid = node_ownergroups[disk_om.ownernode] disksom = [] if nodeid in map_disks_to_node: disksom = map_disks_to_node[nodeid] disksom.append(disk_om) map_disks_to_node[nodeid] = disksom # This section is for ClusterInterface class net_spliter_index = results['clusternetworks'].index("====") clusternetworks = results['clusternetworks'][:net_spliter_index] nodeinterfaces = results['clusternetworks'][net_spliter_index+1:] for interface in nodeinterfaces: intfline = interface.split("|") intf_node = intfline[2] if intf_node in node_ownergroups: interface_om = ObjectMap() interface_om.id = self.prepId(intfline[0]) interface_om.title = intfline[1] interface_om.node = intf_node interface_om.network = intfline[3] interface_om.ipaddresses = intfline[4] interface_om.adapter = intfline[5] interface_om.domain = results['domain'] intfnodeid = node_ownergroups[interface_om.node] intfom = [] if intfnodeid in map_interfaces_to_node: intfom = map_interfaces_to_node[intfnodeid] intfom.append(interface_om) map_interfaces_to_node[intfnodeid] = intfom maps.append(RelationshipMap( compname="os", relname="clusternodes", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterNode", objmaps=map_nodes_oms )) for nodeid, disks in map_disks_to_node.items(): maps.append(RelationshipMap( compname="os/clusternodes/" + nodeid, relname="clusterdisks", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterDisk", objmaps=disks )) for nodeid, interface in map_interfaces_to_node.items(): maps.append(RelationshipMap( compname="os/clusternodes/" + nodeid, relname="clusterinterfaces", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterInterface", objmaps=interface )) # This section is for ClusterNetwork class for network in clusternetworks: netline = network.split("|") netrole = { '0': 'Not allowed', '1': 'Cluster only', '3': 'Cluster and Client' }.get(netline[4], '0') net_om = ObjectMap() net_om.id = self.prepId(netline[0]) net_om.title = netline[1] net_om.description = netline[2] net_om.role = netrole net_om.domain = results['domain'] map_networks_oms.append(net_om) maps.append(RelationshipMap( compname="os", relname="clusternetworks", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterNetwork", objmaps=map_networks_oms )) return maps
def get_db_om(self, om_instance, instance, owner_node, sqlserver, stdout_line): dbobj = stdout_line db = dbobj.split('\t') dbdict = {} for dbitem in db: try: key, value = dbitem.split('---') dbdict[key.lower()] = value.strip() except (ValueError): self.log.info('Error parsing returned values : {0}'.format( dbitem)) lastlogbackupdate = None if ('lastlogbackupdate' in dbdict) \ and (dbdict['lastlogbackupdate'][:8] != '1/1/0001'): lastlogbackupdate = dbdict['lastlogbackupdate'] lastbackupdate = None if ('lastbackupdate' in dbdict) \ and (dbdict['lastbackupdate'][:8] != '1/1/0001'): lastbackupdate = dbdict['lastbackupdate'] om_database = None if ('id' in dbdict): om_database = ObjectMap() om_database.id = self.prepId(instance + dbdict['id']) om_database.title = dbdict['name'][1:-1] om_database.instancename = om_instance.id om_database.version = dbdict['version'] om_database.owner = dbdict['owner'] om_database.lastbackupdate = lastbackupdate om_database.lastlogbackupdate = lastlogbackupdate om_database.isaccessible = dbdict['isaccessible'] om_database.collation = dbdict['collation'] om_database.createdate = str(dbdict['createdate']) om_database.defaultfilegroup = dbdict['defaultfilegroup'] om_database.primaryfilepath = dbdict['primaryfilepath'] om_database.cluster_node_server = '{0}//{1}'.format( owner_node, sqlserver) om_database.systemobject = dbdict['systemobject'] om_database.recoverymodel = dbdict['recoverymodel'] return om_database
def process(self, device, results, log): log.info( "Modeler %s processing data for device %s", self.name(), device.id) sysEnclosure = results.get('Win32_SystemEnclosure', (None,))[0] computerSystem = results.get('Win32_ComputerSystem', (None,))[0] operatingSystem = results.get('Win32_OperatingSystem', (None,))[0] clusterInformation = results.get('MSCluster', ()) exchange_version = results.get('exchange_version') domainController = results.get('ActiveDirectory', (None,)) if exchange_version: exchange_version = exchange_version.stdout[0][:2] if exchange_version.stdout else None if exchange_version: exchange_version = {'6': '2003', '8': '2010', '08': '2010', '14': '2010', '15': '2013'}.get( exchange_version ) maps = [] # Device Map device_om = ObjectMap() try: device_om.snmpSysName = computerSystem.Name device_om.snmpContact = computerSystem.PrimaryOwnerName device_om.snmpDescr = computerSystem.Caption except AttributeError: log.warn('No results returned for Win32_ComputerSystem. Check WMI namespace and DCOM permissions.') device_om.ip_and_hostname = self.get_ip_and_hostname(device.manageIp) # http://office.microsoft.com/en-001/outlook-help/determine-the-version-of-microsoft-exchange-server-my-account-connects-to-HA010117038.aspx if exchange_version: if exchange_version in ['2010', '2013']: device_om.msexchangeversion = 'MSExchange%sIS' % exchange_version else: # We use this attr to find the correct monitoring template device_om.msexchangeversion = 'MSExchangeInformationStore' else: device_om.msexchangeversion = '' # Cluster Information try: clusterlist = [] for cluster in clusterInformation: clusterlist.append(cluster.Name + '.' + computerSystem.Domain) device_om.setClusterMachines = clusterlist except (AttributeError): pass # if NTDS service present then this is a DC if domainController: device_om.domain_controller = True else: device_om.domain_controller = False maps.append(device_om) # Hardware Map hw_om = ObjectMap(compname='hw') try: hw_om.serialNumber = operatingSystem.SerialNumber if operatingSystem else '' except AttributeError: log.warn('No results returned for Win32_OperatingSystem. Check WMI namespace and DCOM permissions.') try: hw_om.tag = sysEnclosure.Tag hw_om.setProductKey = MultiArgs( computerSystem.Model, computerSystem.Manufacturer) except AttributeError: log.warn('No results returned for Win32_SystemEnclosure. Check WMI namespace and DCOM permissions.') if hasattr(operatingSystem, 'TotalVisibleMemorySize'): hw_om.totalMemory = 1024 * int(operatingSystem.TotalVisibleMemorySize) else: log.warn( "Win32_OperatingSystem query did not respond with " "TotalVisibleMemorySize: {0}" .format(pformat(sorted(vars(operatingSystem).keys())))) maps.append(hw_om) # Operating System Map os_om = ObjectMap(compname='os') try: os_om.totalSwap = int(operatingSystem.TotalVirtualMemorySize) * 1024 operatingSystem.Caption = re.sub( r'\s*\S*Microsoft\S*\s*', '', operatingSystem.Caption) osCaption = '{} - {}'.format( operatingSystem.Caption, operatingSystem.CSDVersion) os_om.setProductKey = MultiArgs( osCaption, operatingSystem.Manufacturer) except AttributeError: pass maps.append(os_om) return maps
def collect(self, device, log): self.log = log # Check if the device is a cluster device. isCluster = True if 'Microsoft/Cluster' in device.getDeviceClassName \ else False dbinstance = prepare_zDBInstances(device.zDBInstances) username = device.windows_user password = device.windows_password dblogins = {} eventmessage = 'Error parsing zDBInstances' try: dbinstance = json.loads(dbinstance) users = [el.get('user') for el in filter(None, dbinstance)] if ''.join(users): for el in filter(None, dbinstance): dblogins[el.get('instance')] = dict( username=el.get('user') if el.get('user') else username, password=el.get('passwd') if el.get('passwd') else password, login_as_user=False if el.get('user') else True ) else: for el in filter(None, dbinstance): dblogins[el.get('instance')] = dict( username=username, password=password, login_as_user=True ) results = {'clear': eventmessage} except (ValueError, TypeError, IndexError): # Error with dbinstance names or password results = {'error': eventmessage} defer.returnValue(results) conn_info = self.conn_info(device) conn_info = conn_info._replace(timeout=device.zCollectorClientTimeout - 5) winrs = SQLCommander(conn_info, log) dbinstances = winrs.get_instances_names(isCluster) instances = yield dbinstances maps = {} if not instances: log.info('{}: No output while getting instance names.' ' zWinRMEnvelopeSize may not be large enough.' ' Increase the size and try again.'.format(self.name())) defer.returnValue(maps) maps['errors'] = {} log.debug('WinMSSQL modeler get_instances_names results: {}'.format(instances)) instance_oms = [] database_oms = [] backup_oms = [] jobs_oms = [] server_config = {} sqlhostname = '' for serverconfig in instances.stdout: key, value = serverconfig.split(':', 1) if key == 'instances': serverlist = {} else: serverlist = [] if not value: continue if key in server_config: serverlist = server_config[key] if key == 'instances': instance_version = value.split(':') if len(instance_version) > 1: serverlist[''.join(instance_version[:-1]).strip()] = ''.join(instance_version[-1:]).strip() else: serverlist[value.strip()] = '0' else: serverlist.append(value.strip()) server_config[key] = serverlist if not server_config.get('instances'): eventmessage = 'No MSSQL Servers are installed but modeler is enabled' results = {'error': eventmessage} defer.returnValue(results) sqlhostname = server_config['hostname'][0] # Set value for device sqlhostname property device_om = ObjectMap() device_om.sqlhostname = sqlhostname for instance, version in server_config['instances'].items(): owner_node = '' # Leave empty for local databases. ip_address = None # Leave empty for local databases. # For cluster device, create a new a connection to each node, # which owns network instances. if isCluster: try: owner_node, ip_address, sql_server, instance = instance.split('\\') owner_node = owner_node.strip() sql_server = sql_server.strip() instance = instance.strip() ip_address = ip_address.strip() conn_info = conn_info._replace(hostname=owner_node) if ip_address: conn_info = conn_info._replace(ipaddress=ip_address) else: conn_info = conn_info._replace(ipaddress=owner_node) winrs = SQLCommander(conn_info, log) except ValueError: log.error('Malformed data returned for instance {}'.format( instance)) continue if instance not in dblogins: log.debug("DB Instance {0} found but was not set in zDBInstances. " "Using default credentials.".format(instance)) instance_title = instance if instance == 'MSSQLSERVER': instance_title = sqlserver = sqlhostname else: sqlserver = '{0}\{1}'.format(sqlhostname, instance) if isCluster: if instance == 'MSSQLSERVER': instance_title = sqlserver = sql_server else: sqlserver = '{0}\{1}'.format(sql_server, instance) om_instance = ObjectMap() om_instance.id = self.prepId(instance_title) if instance == 'MSSQLSERVER': om_instance.perfmon_instance = 'SQLServer' om_instance.title = '{}(MSSQLSERVER)'.format(instance_title) else: om_instance.perfmon_instance = 'MSSQL${}'.format(instance) om_instance.title = instance_title om_instance.instancename = instance om_instance.sql_server_version = version om_instance.cluster_node_server = '{0}//{1}'.format( owner_node, sqlserver) om_instance.owner_node_ip = ip_address instance_oms.append(om_instance) # Look for specific instance creds first try: sqlusername = dblogins[instance]['username'] sqlpassword = dblogins[instance]['password'] login_as_user = dblogins[instance]['login_as_user'] except KeyError: # Try default MSSQLSERVER creds try: sqlusername = dblogins['MSSQLSERVER']['username'] sqlpassword = dblogins['MSSQLSERVER']['password'] login_as_user = dblogins['MSSQLSERVER']['login_as_user'] except KeyError: # Use windows auth sqlusername = username sqlpassword = password login_as_user = True sql_version = int(om_instance.sql_server_version.split('.')[0]) sqlConnection = SqlConnection(sqlserver, sqlusername, sqlpassword, login_as_user, sql_version).sqlConnection db_sqlConnection = [] # Get database information # smo optimization for faster loading db_sqlConnection.append("$ob = New-Object Microsoft.SqlServer.Management.Smo.Database;" "$def = $server.GetDefaultInitFields($ob.GetType());" "$server.SetDefaultInitFields($ob.GetType(), $def);") db_sqlConnection.append('write-host "====Databases";') db_sqlConnection.append('$server.Databases | foreach {' 'write-host \"Name---\" $_,' '\"`tVersion---\" $_.Version,' '\"`tIsAccessible---\" $_.IsAccessible,' '\"`tID---\" $_.ID,' '\"`tOwner---\" $_.Owner,' '\"`tLastBackupDate---\" $_.LastBackupDate,' '\"`tCollation---\" $_.Collation,' '\"`tCreateDate---\" $_.CreateDate,' '\"`tDefaultFileGroup---\" $_.DefaultFileGroup,' '\"`tPrimaryFilePath---\" $_.PrimaryFilePath,' '\"`tLastLogBackupDate---\" $_.LastLogBackupDate,' '\"`tSystemObject---\" $_.IsSystemObject,' '\"`tRecoveryModel---\" $_.DatabaseOptions.RecoveryModel' '};') # Get SQL Backup Jobs information backup_sqlConnection = [] # smo optimization for faster loading backup_sqlConnection.append("$ob = New-Object Microsoft.SqlServer.Management.Smo.BackupDevice;" "$def = $server.GetDefaultInitFields($ob.GetType());" "$server.SetDefaultInitFields($ob.GetType(), $def);") backup_sqlConnection.append('write-host "====Backups";') # Get database information backup_sqlConnection.append('try{$server.BackupDevices | foreach {' 'write-host \"Name---\" $_.Name,' '\"`tDeviceType---\" $_.BackupDeviceType,' '\"`tPhysicalLocation---\" $_.PhysicalLocation,' '\"`tStatus---\" $_.State' '}}catch{ continue };') # Get SQL Jobs information job_sqlConnection = [] # smo optimization for faster loading job_sqlConnection.append("$ob = New-Object Microsoft.SqlServer.Management.Smo.Agent.Job;" "$def = $server.GetDefaultInitFields($ob.GetType());" "$server.SetDefaultInitFields($ob.GetType(), $def);") job_sqlConnection.append('write-host "====Jobs";') job_sqlConnection.append("try {") job_sqlConnection.append("$server.JobServer.Jobs | foreach {") job_sqlConnection.append('write-host \"job_jobname---\" $_.Name,') job_sqlConnection.append('\"job_enabled---\" $_.IsEnabled,') job_sqlConnection.append('\"job_jobid---\" $_.JobID,') job_sqlConnection.append('\"job_description---\" $_.Description,') job_sqlConnection.append('\"job_datecreated---\" $_.DateCreated,') job_sqlConnection.append('\"job_username---\" $_.OwnerLoginName') job_sqlConnection.append("}}catch { continue; }") version_sqlConnection = [] if isCluster: version_sqlConnection.append("write-host \"====Version\";") version_sqlConnection.append("$dbmaster = $server.Databases['master'];") version_sqlConnection.append('$query = \\"SELECT SERVERPROPERTY(\'productversion\') as version\\";') version_sqlConnection.append("$res = $dbmaster.ExecuteWithResults($query);") version_sqlConnection.append("write-host $res.tables[0].rows[0].version;") instance_info = yield winrs.run_command( ''.join(getSQLAssembly(int(om_instance.sql_server_version.split('.')[0])) + sqlConnection + db_sqlConnection + backup_sqlConnection + job_sqlConnection + version_sqlConnection) ) log.debug('Modeling databases, backups, jobs results: {}'.format(instance_info)) check_username(instance_info, instance, log) maps['errors'][om_instance.id] = instance_info.stderr stdout = filter_sql_stdout(instance_info.stdout) try: db_index = stdout.index('====Databases') except ValueError: db_index = None try: backup_index = stdout.index('====Backups') except ValueError: backup_index = None try: job_index = stdout.index('====Jobs') except ValueError: job_index = None try: version_index = stdout.index('====Version') except ValueError: version_index = None if db_index is not None and backup_index is not None: for stdout_line in stdout[db_index + 1:backup_index]: if stdout_line == 'assembly load error': break om_database = self.get_db_om(om_instance, instance, owner_node, sqlserver, stdout_line) if om_database: database_oms.append(om_database) if backup_index is not None and job_index is not None: for stdout_line in stdout[backup_index + 1:job_index]: om_backup = self.get_backup_om(om_instance, instance, stdout_line) if om_backup: backup_oms.append(om_backup) if job_index is not None: job_line = '' for stdout_line in stdout[job_index + 1:]: # account for newlines in description if not job_line: job_line = stdout_line else: job_line = '\n'.join((job_line, stdout_line)) if 'job_username---' not in stdout_line: continue om_job = self.get_job_om(device, sqlserver, om_instance, owner_node, job_line) if om_job: jobs_oms.append(om_job) job_line = '' if isCluster and version_index is not None: try: om_instance.sql_server_version = stdout[version_index + 1].strip() except Exception: log.debug('Version not found for om_instance %s', om_instance.id) maps['clear'] = eventmessage maps['databases'] = database_oms maps['instances'] = instance_oms maps['backups'] = backup_oms maps['jobs'] = jobs_oms maps['device'] = device_om defer.returnValue(maps)
def iloInterface(self, manageIp): om = ObjectMap({}, compname = "os", modname = "Products.ZenModel.IpInterface") om.id = self.prepId("iLO Network Interface") om.title = om.id om.interfaceName = om.id om.type = "ethernetCsmacd" om.speed = 100000000 om.mtu = 1500 om.ifindex = "1" om.adminStatus = 1 om.operStatus = 1 om.monitor = False om.setIpAddresses = [manageIp, ] return RelationshipMap(relname = "interfaces", compname = "os", modname = "Products.ZenModel.IpInterface", objmaps = [om,])
def process(self, device, results, log): """collect CIM information from this device""" log.info('processing %s for device %s', self.name(), device.id) maps = [] rm = self.relMap() instances = results.get("CIM_ComputerSystem") if not instances: return rm sysnames = self._getSysnames(device, results, "CIM_ComputerSystem") sysname = sysnames[0] for inst in instances: subsysname = (inst.get("_sysname") or "").lower() if subsysname not in sysnames: continue try: inst.update(self._getPackage(results, inst)) productKey = inst.get("setProductKey") if (len(instances)==1) or (not maps and (sysname in subsysname)): om = ObjectMap() om.snmpindex = inst.get("setPath") or "" om.snmpSysName = subsysname om.snmpDescr = inst.get("_descr") or "" om.snmpContact = inst.get("_contact") or "" if productKey: om.setHWProductKey = MultiArgs(productKey, inst.get("_manuf") or "Unknown") serialNumber = inst.get("serialNumber") if serialNumber: om.setHWSerialNumber = serialNumber tag = inst.get("tag") if tag: om.setHWTag = tag maps.append(om) continue if not productKey: continue self._setCimStatusName(inst) om = self.objectMap(inst) om.id = self.prepId(inst.get("_sysname") or "") if not om.id: continue om.setProductKey = MultiArgs(productKey, inst.get("_manuf") or "Unknown") om.slot = self._getSlot(results, inst) collections = self._getCollections(results, inst) if collections: om.setCollections = collections statPath = self._getStatPath(results, inst) if statPath: om.setStatPath = statPath om.monitor = self._monitor(inst) rm.append(om) except: log.warning('processing error') if len(rm.maps) > 0: maps.append(rm) return maps
def process(self, device, results, log): log.info( "Modeler %s processing data for device %s", self.name(), device.id) sysEnclosure = results.get('Win32_SystemEnclosure', (None,))[0] computerSystem = results.get('Win32_ComputerSystem', (None,))[0] operatingSystem = results.get('Win32_OperatingSystem', (None,))[0] clusterInformation = results.get('MSCluster', ()) maps = [] # Device Map device_om = ObjectMap() device_om.snmpSysName = computerSystem.Name device_om.snmpContact = computerSystem.PrimaryOwnerName device_om.snmpDescr = computerSystem.Caption # Cluster Information try: clusterlist = [] for cluster in clusterInformation: clusterlist.append(cluster.Name) device_om.setClusterMachines = clusterlist except (AttributeError): pass maps.append(device_om) # Hardware Map hw_om = ObjectMap(compname='hw') hw_om.serialNumber = sysEnclosure.SerialNumber hw_om.tag = sysEnclosure.Tag hw_om.setProductKey = MultiArgs( computerSystem.Model, computerSystem.Manufacturer) if hasattr(operatingSystem, 'TotalVisibleMemorySize'): hw_om.totalMemory = 1024 * int(operatingSystem.TotalVisibleMemorySize) else: log.warn( "Win32_OperatingSystem query did not respond with " "TotalVisibleMemorySize: {0}" .format(pformat(sorted(vars(operatingSystem).keys())))) maps.append(hw_om) # Operating System Map os_om = ObjectMap(compname='os') os_om.totalSwap = int(operatingSystem.TotalVirtualMemorySize) * 1024 operatingSystem.Caption = re.sub( r'\s*\S*Microsoft\S*\s*', '', operatingSystem.Caption) osCaption = '{} - {}'.format( operatingSystem.Caption, operatingSystem.CSDVersion) os_om.setProductKey = MultiArgs( osCaption, operatingSystem.Manufacturer) maps.append(os_om) return maps
def process(self, device, results, log): log.info('Modeler %s processing data for device %s', self.name(), device.id) maps = [] map_resources_oms = [] ownergroups = {} map_apps_to_resource = {} nodes = results['nodes'] cs_om = ObjectMap() cs_om.setClusterHostMachines = nodes maps.append(cs_om) # Cluster Resource Maps resources = results['resources'] # This section is for ClusterService class for resource in resources: resourceline = resource.split("|") res_om = ObjectMap() res_om.id = self.prepId(resourceline[5]) res_om.title = resourceline[0] res_om.coregroup = resourceline[1] res_om.ownernode = resourceline[2] res_om.state = resourceline[3] res_om.description = resourceline[4] res_om.priority = resourceline[6] if res_om.title not in ownergroups: ownergroups[res_om.title] = res_om.id map_resources_oms.append(res_om) # Cluster Application and Services # This section is for ClusterResrouce class applications = results['apps'] for app in applications: appline = app.split("|") app_om = ObjectMap() app_om.id = self.prepId('res-{0}'.format(appline[0])) app_om.title = appline[0] app_om.ownernode = appline[2] app_om.description = appline[4] app_om.ownergroup = appline[1] app_om.state = appline[3] groupid = ownergroups[app_om.ownergroup] appsom = [] if groupid in map_apps_to_resource: appsom = map_apps_to_resource[groupid] appsom.append(app_om) map_apps_to_resource[groupid] = appsom maps.append(RelationshipMap( compname="os", relname="clusterservices", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterService", objmaps=map_resources_oms)) for resourceid, apps in map_apps_to_resource.items(): maps.append(RelationshipMap( compname="os/clusterservices/" + resourceid, relname="clusterresources", modname="ZenPacks.zenoss.Microsoft.Windows.ClusterResource", objmaps=apps)) return maps
def parse_result(self, dsconfs, result): if result.exit_code != 0: counters = [dsconf.params['resource'] for dsconf in dsconfs] log.info( 'Non-zero exit code ({0}) for counters, {1}, on {2}' .format( result.exit_code, counters, dsconf.device)) return # Parse values try: for resourceline in result.stdout: name, iscoregroup, ownernode, state, \ description, nodeid, priority = resourceline.split('|') dsconf0 = dsconfs[0] compObject = ObjectMap() compObject.id = prepId(nodeid) compObject.title = name compObject.coregroup = iscoregroup compObject.ownernode = ownernode compObject.state = state compObject.description = description compObject.priority = priority compObject.compname = dsconf0.params['contextcompname'] compObject.modname = dsconf0.params['contextmodname'] compObject.relname = dsconf0.params['contextrelname'] for dsconf in dsconfs: try: value = (name, state, compObject) timestamp = int(time.mktime(time.localtime())) yield dsconf, value, timestamp except(AttributeError): log.debug("No value was returned for {0}".format(dsconf.params['counter'])) except (AttributeError, UnboundLocalError): log.debug('Error in parsing cluster service data')
def process(self, device, results, log): log.info( "Modeler %s processing data for device %s", self.name(), device.id) try: # assume valid results returned sysEnclosure = results.get('Win32_SystemEnclosure', None)[0] except Exception: # results contains Win32_SystemEnclosure as a key, but it's empty sysEnclosure = None computerSystem = results.get('Win32_ComputerSystem', (None,))[0] operatingSystem = results.get('Win32_OperatingSystem', (None,))[0] clusterInformation = results.get('MSCluster', ()) exchange_version = results.get('exchange_version') if exchange_version: exchange_version = exchange_version.stdout[0][:2] if exchange_version.stdout else None if exchange_version: exchange_version = {'6': '2003', '8': '2010', '08': '2010', '14': '2010', '15': '2013'}.get( exchange_version ) maps = [] if not computerSystem: # if no results for computerSystem, then there is a WMI permission error log.warn('No results returned for OperatingSystem plugin.' ' Check WMI namespace and DCOM permissions.') return maps # Device Map device_om = ObjectMap() # safely get name, contact, desc sys_name = getattr(computerSystem, 'Name', None) or getattr(operatingSystem, 'CSName', None) or 'Unknown' device_om.snmpSysName = sys_name.strip() contact = getattr(computerSystem, 'PrimaryOwnerName', None) or getattr(operatingSystem, 'RegisteredUser', None) or 'Unknown' device_om.snmpContact = contact.strip() desc = getattr(computerSystem, 'Caption', None) or getattr(operatingSystem, 'Caption', None) or 'Unknown' device_om.snmpDescr = desc.strip() device_om.ip_and_hostname = self.get_ip_and_hostname(device.manageIp) # http://office.microsoft.com/en-001/outlook-help/determine-the-version-of-microsoft-exchange-server-my-account-connects-to-HA010117038.aspx if exchange_version: if exchange_version in ['2010', '2013']: device_om.msexchangeversion = 'MSExchange%sIS' % exchange_version else: # We use this attr to find the correct monitoring template device_om.msexchangeversion = 'MSExchangeInformationStore' else: device_om.msexchangeversion = '' # Cluster Information clusterlist = [] for cluster in clusterInformation: clusterlist.append(getattr(cluster, 'Name', '') + '.' + getattr(computerSystem, 'Domain', '')) device_om.setClusterMachines = clusterlist # if domainrole is 4 or 5 then this is a DC # Standalone Workstation (0) # Member Workstation (1) # Standalone Server (2) # Member Server (3) # Backup Domain Controller (4) # Primary Domain Controller (5) device_om.domain_controller = False if getattr(computerSystem, 'DomainRole', '0') in (BACKUPDC, PRIMARYDC) or\ getattr(operatingSystem, 'ProductType', '0') == OS_DOMAIN_CONTROLLER: device_om.domain_controller = True maps.append(device_om) # Hardware Map hw_om = ObjectMap(compname='hw') hw_om.serialNumber = getattr(operatingSystem, 'SerialNumber', '') if operatingSystem else '' hw_om.tag = getattr(sysEnclosure, 'Tag', 'Unknown') model = getattr(computerSystem, 'Model', 'Unknown') manufacturer = getattr(computerSystem, 'Manufacturer', getattr(operatingSystem, 'Manufacturer', 'Microsoft Corporation')) hw_om.setProductKey = MultiArgs( model, manufacturer) try: hw_om.totalMemory = 1024 * int(operatingSystem.TotalVisibleMemorySize) except AttributeError: log.warn( "Win32_OperatingSystem query did not respond with " "TotalVisibleMemorySize: {0}" .format(pformat(sorted(vars(operatingSystem).keys())))) maps.append(hw_om) # Operating System Map os_om = ObjectMap(compname='os') os_om.totalSwap = int(getattr(operatingSystem, 'TotalVirtualMemorySize', '0')) * 1024 osCaption = getattr(operatingSystem, 'Caption', None) or 'Unknown' operatingSystem.Caption = re.sub( r'\s*\S*Microsoft\S*\s*', '', osCaption) osCaption = getattr(operatingSystem, 'Caption', 'Unknown') CSDVersion = getattr(operatingSystem, 'CSDVersion', 'Unknown') if CSDVersion: osCaption += ' - {}'.format(CSDVersion) os_om.setProductKey = MultiArgs( osCaption, getattr(operatingSystem, 'Manufacturer', 'Microsoft Corporation')) maps.append(os_om) return maps