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
Example #4
0
 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
Example #5
0
    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')
Example #7
0
    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
Example #8
0
    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
Example #9
0
    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
Example #12
0
    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
Example #17
0
 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
Example #20
0
    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)})
Example #25
0
    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
Example #27
0
 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
Example #28
0
    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 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
Example #32
0
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
Example #33
0
    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 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 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)
Example #42
0
    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