Ejemplo n.º 1
0
def createObjects(runtime, realmUtil, trackedZones, trackedIPs, recordData,
                  domainName, ownerName, trackEveryIpInDNS, trackEveryIpInDB,
                  trackIPsInRealm, ipAddrToIdDict):
    """Conditionally create IPs and link in the records."""
    recordId = None
    ipId = None
    ## If we are told to create all DNS content, do not check values
    if not trackEveryIpInDNS:
        ## Otherwise, we have two more conditions to check...
        ## if told to create DNS for all IPs already resident in the DB
        if trackEveryIpInDB:
            if recordData in ipAddrToIdDict:
                ipId = ipAddrToIdDict[recordData]
                runtime.logger.report('   trackedByDB using id: {ipId!r}',
                                      ipId=ipId)
                addObject(runtime, 'IpAddress', uniqueId=ipId)
            elif trackIPsInRealm:
                if not realmUtil.isIpInRealm(recordData):
                    runtime.logger.report(
                        '   ... skipping IP {recordData!r} because it is neither in the DB nor in the realm configuration',
                        recordData=recordData)
                    return recordId
            else:
                runtime.logger.report(
                    '   ... skipping IP {recordData!r} because it is not in the DB',
                    recordData=recordData)
                return recordId
        elif trackIPsInRealm:
            if not realmUtil.isIpInRealm(recordData):
                runtime.logger.report(
                    '   ... skipping IP {recordData!r} because it is not in the realm configuration',
                    recordData=recordData)
                return recordId

    ## Create the IP first (if not using a handle from the DB)
    if ipId is None:
        try:
            ipId = createNewIp(runtime, trackedIPs, recordData)
        except ValueError:
            runtime.logger.report('ValueError in getThisIp: {valueError!r}',
                                  valueError=str(sys.exc_info()[1]))
            return recordId

    ## Create the zone if necessary
    if domainName not in trackedZones.keys():
        ## Add the zone onto (or back onto) the result set
        zoneId, exists = addObject(runtime, 'Domain', name=domainName)
        trackedZones[domainName] = zoneId
    zoneId = trackedZones[domainName]

    ## Create the DNS record
    recordId, exists = addObject(runtime,
                                 'NameRecord',
                                 name=ownerName,
                                 value=recordData)
    addLink(runtime, 'Enclosed', zoneId, recordId)
    addLink(runtime, 'Usage', ipId, recordId)

    ## end createObjects
    return recordId
def trackWebResponse(runtime, ipAddress, ipObjectId, port, url, responseCode,
                     responseText, title):
    """Create the IP, Port, and WebEnabledEndpoint."""
    ## Recreate the IP by the identifier
    addObject(runtime, 'IpAddress', uniqueId=ipObjectId)
    ## Create TcpIpPort
    tcpIpPortId, portExists = addObject(runtime,
                                        'TcpIpPort',
                                        name=str(port),
                                        port=int(port),
                                        ip=ipAddress,
                                        port_type='tcp',
                                        is_tcp=True)
    ## Don't need to HTML encode all, but definitely double quotes for JSON
    ## result object; and truncate in case the response was too large
    responseText = responseText.replace('"', '"')[:4096]
    ## Create WebEnabledEndpoint
    webId, certExists = addObject(runtime,
                                  'WebEnabledEndpoint',
                                  url=url,
                                  ip=ipAddress,
                                  port=port,
                                  title=title,
                                  response_code=responseCode,
                                  response_text=responseText)
    ## Links
    addLink(runtime, 'Enclosed', ipObjectId, tcpIpPortId)
    addLink(runtime, 'Enclosed', tcpIpPortId, webId)

    ## end trackWebResponse
    return
def startJob(runtime):
    """Standard job entry point.

	Arguments:
	  runtime (dict)   : object used for providing I/O for jobs and tracking
	                     the job thread through its runtime
	"""
    client = None
    try:
        ## Configure shell client
        client = getClient(runtime, commandTimeout=30)
        if client is not None:
            ## Get a handle on our Node in order to link objects in this job
            nodeId = runtime.endpoint.get('data').get('container')
            ## Get all related IPs
            ips = {}
            for ip in runtime.endpoint.get('children',
                                           {}).get('IpAddress', []):
                ipObjectId = ip.get('identifier')
                ipAddress = ip.get('data').get('address')
                ips[ipAddress] = ipObjectId

            ## Open client session before starting the work
            client.open()

            ## First query for SQL instance name and IDs
            instances = {}
            findInstances(runtime, client, instances)

            ## Only continue if we found SQL instances
            if len(instances) <= 0:
                ## Job executed fine, but didn't find what it was looking for
                runtime.setInfo('SQL Server not found')
            else:
                addObject(runtime, 'Node', uniqueId=nodeId)
                #runtime.results.addObject('Node', uniqueId=nodeId)
                for instanceName, instanceData in instances.items():
                    regInstancePath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\{}'.format(
                        instanceData.get('id'))
                    dbContextId = qualifyInstance(runtime, client,
                                                  instanceName, instanceData,
                                                  regInstancePath, nodeId)
                    getConnectionParameters(runtime, client, instanceName,
                                            instanceData, regInstancePath,
                                            dbContextId)

            ## Update the runtime status to success
            if runtime.getStatus() == 'UNKNOWN':
                runtime.status(1)

    except:
        runtime.setError(__name__)

    with suppress(Exception):
        if client is not None:
            client.close()

    ## end startJob
    return
Ejemplo n.º 4
0
def createObjects(runtime, shortname, domain, description, deviceOID, location,
                  firmware, serialNumber, model, assetId, endpoint, ips,
                  protocolId):
    """Create objects and links in our results."""
    try:
        ## First create the node
        nodeId, exists = addObject(runtime,
                                   'Node',
                                   hostname=shortname,
                                   domain=domain,
                                   description=description,
                                   snmp_oid=deviceOID,
                                   location=location)

        ## Now create the hardware
        if serialNumber is not None:
            hardwareId, exists = addObject(runtime,
                                           'HardwareNode',
                                           serial_number=serialNumber,
                                           bios_info=firmware,
                                           model=model,
                                           asset_tag=assetId)
            addLink(runtime, 'Usage', nodeId, hardwareId)

        ## Now create the IPs
        for ip in ips:
            with suppress(ValueError):
                ipId, exists = addIp(runtime, address=ip)
                addLink(runtime, 'Usage', nodeId, ipId)
        ## In case the IP we've connected in on isn't in the IP table list:
        if endpoint not in ips:
            with suppress(ValueError):
                ipId, exists = addIp(runtime, address=endpoint)
                addLink(runtime, 'Usage', nodeId, ipId)

        ## Now create the SNMP object
        realm = runtime.jobMetaData.get('realm')
        snmpId, exists = addObject(runtime,
                                   'SNMP',
                                   container=nodeId,
                                   ipaddress=endpoint,
                                   protocol_reference=protocolId,
                                   realm=realm,
                                   node_type='Unknown')
        addLink(runtime, 'Enclosed', nodeId, snmpId)

        ## Update the runtime status to success
        runtime.status(1)

    except:
        runtime.setError(__name__)

    ## end createObjects
    return
Ejemplo n.º 5
0
def createObjects(runtime, client, realm):
	"""Create and connect the node and REST object."""
	## Get necessary info from the client
	(endpoint, reference, port, url) = client.restDetails()
	## Create the node
	nodeId, exists = addObject(runtime, 'Node', hostname=endpoint, partial=True)
	## Create a REST object to leverage for future connections
	restId, exists = addObject(runtime, 'REST', container=nodeId, ipaddress=endpoint, protocol_reference=reference, realm=realm, port=port, base_url=url, node_type='OCP')
	ipId, exists = addIp(runtime, address=endpoint)
	## And connect the objects
	addLink(runtime, 'Enclosed', nodeId, restId)
	addLink(runtime, 'Usage', nodeId, ipId)
Ejemplo n.º 6
0
def createAndMapAliases(runtime, targetId, targetName, targetDomain,
                        trackedZones, domainDict, knownCnames):
    """Create and link associated aliases."""
    try:
        runtime.logger.report('    Looking for aliases of {targetName!r}',
                              targetName=targetName)
        ## Map through aliases if any exist
        if targetDomain in domainDict.keys():
            domainCnameDict = domainDict[targetDomain]
            if targetName in domainCnameDict.keys():
                (sourceName, sourceDomain) = domainCnameDict[targetName]
                runtime.logger.report(
                    '      {targetName!r} has related alias {sourceName!r}',
                    targetName=targetName,
                    sourceName=sourceName)
                knownCnames[targetName] = 1

                ## Create the zone if necessary
                if sourceDomain not in trackedZones.keys():
                    ## Add the zone onto (or back onto) the result set
                    zoneId, exists = addObject(runtime,
                                               'Domain',
                                               name=sourceDomain)
                    trackedZones[sourceDomain] = zoneId
                zoneId = trackedZones[sourceDomain]

                ## Create the record
                sourceId, exists = addObject(runtime,
                                             'NameRecord',
                                             name=sourceName,
                                             value=targetName)
                addLink(runtime, 'Enclosed', zoneId, sourceId)
                addLink(runtime, 'Route', sourceId, targetId)

                ## See if there are aliases for this alias
                createAndMapAliases(runtime, sourceId, sourceName,
                                    sourceDomain, trackedZones, domainDict,
                                    knownCnames)

    except:
        stacktrace = traceback.format_exception(sys.exc_info()[0],
                                                sys.exc_info()[1],
                                                sys.exc_info()[2])
        runtime.logger.error('Failure in createAndMapAliases: {stacktrace!r}',
                             stacktrace=stacktrace)

    ## end createAndMapAliases
    return
Ejemplo n.º 7
0
def createObject(runtime, nodeId, properties):
    """Create the file object and link it to the node.

	Arguments:
	  runtime (dict)     : used for providing input into jobs and tracking
	                       the job thread through the life of its runtime
	  nodeId (string)    : 'object_id' of the Node that our client is connected
	                       to; not used here... just stubbed for common practice
	  properties (dict)  : dictionary with key:value pairs from command output
	"""
    try:
        attributes = {}
        setAttribute(properties, 'Name', attributes, 'name')
        setAttribute(properties, 'FullName', attributes, 'path')
        setAttribute(properties, 'Extension', attributes, 'extension')
        ## In production scenario, convert string dates to datetime type before
        setAttribute(properties, 'CreationTime', attributes, 'file_created')
        setAttribute(properties, 'LastWriteTime', attributes, 'file_modified')
        setAttribute(properties, 'Hash', attributes, 'md5hash')

        ## Create the file
        fileId, exists = addObject(runtime, 'FileCustom', **attributes)
        ## Link it to the node
        addLink(runtime, 'Enclosed', nodeId, fileId)

    except:
        stacktrace = traceback.format_exception(sys.exc_info()[0],
                                                sys.exc_info()[1],
                                                sys.exc_info()[2])
        runtime.logger.error(' Failure in createObject: {stacktrace!r}',
                             stacktrace=stacktrace)

    ## end createObject
    return
Ejemplo n.º 8
0
def trackCertificate(runtime, ipAddress, ipObjectId, port, cert):
    """Create the IP, Port, and SSLCertificate."""
    addObject(runtime, 'IpAddress', uniqueId=ipObjectId)
    ## Create TcpIpPort
    tcpIpPortId, portExists = addObject(runtime,
                                        'TcpIpPort',
                                        name=str(port),
                                        port=int(port),
                                        ip=ipAddress,
                                        port_type='tcp',
                                        is_tcp=True)
    ## Create SSLCertificate
    sslCertificateId, certExists = addObject(runtime, 'SSLCertificate', **cert)
    ## Links
    addLink(runtime, 'Enclosed', ipObjectId, tcpIpPortId)
    addLink(runtime, 'Enclosed', tcpIpPortId, sslCertificateId)
def getNamedPipes(runtime, client, hostname, instanceName, regInstancePath,
                  dbContextId):
    """Find out whether Named Pipes are enabled."""
    path = r'{}\MSSQLServer\SuperSocketNetLib\Np'.format(regInstancePath)
    command = 'Get-ItemProperty -Path "' + path + '" | %{$_.DisplayName,$_.Enabled,$_.PipeName -Join ":==:"}'
    (stdOut, stdError, hitProblem) = client.run(command, 5)
    ## Sample output:
    ## ===================================
    ## Named Pipes:==:0:==:\\.\pipe\sql\query
    ## ===================================
    if len(stdOut) > 0:
        (protocol, enabled, pipeName) = stdOut.split(':==:')
        if enabled != '0':
            attributes = {}
            attributes['name'] = instanceName
            attributes['protocol'] = protocol
            attributes['logical_context'] = pipeName
            attributes['db_type'] = 'SqlServer'
            attributes['source'] = 'Local'
            attributes['hostname'] = hostname

            ## Create Named Pipes connection parameter and link to dbContext
            connectionParameterId, exists = addObject(runtime,
                                                      'DBConnectionParameter',
                                                      **attributes)
            addLink(runtime, 'Enclosed', dbContextId, connectionParameterId)

            ## Debugging aid
            runtime.logger.report('   {} enabled on instance {}:'.format(
                protocol, instanceName))

    ## end getNamedPipes
    return
def qualifyInstance(runtime, client, instanceName, instanceData,
                    regInstancePath, nodeId):
    """Request details from each existing database instance."""
    dbContextId = None
    try:
        instanceId = instanceData.get('id')
        ## C:\Program Files\Microsoft SQL Server\MSSQL11.TEST\Setup
        setupPath = '{}\Setup'.format(regInstancePath)
        command = 'Get-ItemProperty -Path "' + setupPath + '" | %{$_.Version,$_.PatchLevel,$_.Edition,$_.EditionType,$_.SqlProgramDir,$_.SQLPath -Join ":==:"}'
        (stdOut, stdError, hitProblem) = client.run(command, 10)
        ## Sample output:
        ## ===================================
        ## 10.50.1600.1:==:10.50.1617.0:==:Express Edition:==:Express Edition with Advanced Services:==:c:\Program Files\Microsoft SQL Server\:==:c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL
        ## 11.0.2100.60:==:11.0.2100.60:==:Express Edition:==:Express Edition:==:C:\Program Files\Microsoft SQL Server\:==:C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPTRACK201\MSSQL
        ## 13.2.5026.0:==:13.2.5026.0:==:Developer Edition:==:Developer Edition:==:C:\Program Files\Microsoft SQL Server\:==:C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL
        ## ===================================

        if hitProblem:
            raise EnvironmentError(
                'Problem gathering details on instance {}'.format(instanceId))
        if (stdOut is None or len(stdOut) <= 0):
            runtime.logger.report(
                'No details found on instance {}'.format(instanceId))
            if stdError is not None:
                runtime.logger.report('  Error: {stdError!r}',
                                      stdError=stdError)
        else:
            (version, patchLevel, edition, editionType, sqlProgramDir,
             sqlPath) = stdOut.split(':==:')
            ## Create the attributes to send to addObject
            attr = {}
            attr['name'] = instanceName
            attr['path'] = sqlPath
            attr['version'] = version
            attr['patch_level'] = patchLevel
            attr['edition'] = edition
            attr['edition_type'] = editionType
            attr['program_dir'] = sqlProgramDir

            ## Create the DB context object and link to the Node
            dbContextId, exists = addObject(runtime, 'SqlServerContext',
                                            **attr)
            addLink(runtime, 'Enclosed', nodeId, dbContextId)

            ## Debugging aid
            runtime.logger.report(
                'Setup info on instance {}:'.format(instanceName))
            runtime.logger.report('   version: {}'.format(version))
            runtime.logger.report('   patchLevel: {}'.format(patchLevel))
            runtime.logger.report('   edition: {}'.format(edition))
            runtime.logger.report('   editionType: {}'.format(editionType))
            runtime.logger.report('   sqlProgramDir: {}'.format(sqlProgramDir))
            runtime.logger.report('   sqlPath: {}'.format(sqlPath))

    except:
        runtime.setError(__name__)

    ## end qualifyInstance
    return dbContextId
def getTcpIp(runtime, client, hostname, instanceName, regInstancePath,
             dbContextId):
    """Find out whether TCP/IP is enabled."""
    tcpPath = r'{}\MSSQLServer\SuperSocketNetLib\TCP'.format(regInstancePath)
    command = 'Get-ItemProperty -Path "' + tcpPath + '" | %{$_.DisplayName,$_.Enabled,$_.ListenOnAllIPs,$_.KeepAlive -Join ":==:"}'
    (stdOut, stdError, hitProblem) = client.run(command, 5)
    ## Sample output:
    ## ===================================
    ## TCP/IP:==:1:==:1:==:30000
    ## ===================================
    if len(stdOut) > 0:
        (protocol, enabled, listenOnAllIPs, keepAlive) = stdOut.split(':==:')
        if enabled == '0':
            return
        runtime.logger.report('   {} enabled on instance {}:'.format(
            protocol, instanceName))
        runtime.logger.report('     enabled: {}'.format(enabled))
        runtime.logger.report('     listenOnAllIPs: {}'.format(listenOnAllIPs))
        runtime.logger.report('     keepAlive: {}'.format(keepAlive))

        ## Get all TCP/IP settings
        command = 'Get-ChildItem -Path "' + tcpPath + '" | foreach { $_.PSChildName }'
        (stdOut, stdError, hitProblem) = client.run(command, 5)
        ## Sample output:
        ## ===================================
        ## IP1
        ## IP2
        ## ...
        ## IPAll
        ## ===================================
        tcpIpEntries = []
        for entry in stdOut.splitlines():
            if entry.strip().lower() == 'ipall':
                (tcpPortAll,
                 tcpDynamicPortAll) = getIpAllEntry(runtime, client,
                                                    instanceName, protocol,
                                                    tcpPath,
                                                    entry.strip().lower())
            else:
                getTcpIpEntry(runtime, client, instanceName, protocol,
                              hostname, tcpPath,
                              entry.strip().lower(), tcpIpEntries)

        for entry in tcpIpEntries:
            normalizePort(entry, tcpPortAll, tcpDynamicPortAll)
            if entry['port'] > 0:
                ## Create TCP/IP connection parameter and link to dbContext
                connectionParameterId, exists = addObject(
                    runtime, 'DBConnectionParameter', **entry)
                addLink(runtime, 'Enclosed', dbContextId,
                        connectionParameterId)

    ## end getTcpIp
    return
def createObject(runtime, nodeId, properties):
	attributes = {}
	setAttribute(properties, 'Name', attributes, 'name')
	setAttribute(properties, 'FullName', attributes, 'path')
	setAttribute(properties, 'Extension', attributes, 'extension')
	setAttribute(properties, 'CreationTime', attributes, 'file_created')
	setAttribute(properties, 'LastWriteTime', attributes, 'file_modified')
	setAttribute(properties, 'Hash', attributes, 'md5hash')
	## Create files and link to the node
	fileId = addObject(runtime, 'FileCustom', **attributes)
	addLink(runtime, 'Enclosed', nodeId, fileId)
Ejemplo n.º 13
0
def startNormalization(runtime, queryResult, flatenedResult, transformFile, transformName):
	"""Perform data normalization on a result, according to the tranformation file."""
	## Don't use dictionary.get(); I want to stop if class/attrs are missing
	classToCreate = transformFile['classToCreate']
	mappedAttributes = {}
	containerClass = None
	containerId = None
	attributes = transformFile['attributes']
	for name,data in attributes.items():
		mappingRule = data.get('mappingRule')
		if name == 'container':
			containerClass = data.get('class')
			containerId = getAttribute(flatenedResult, mappingRule, 'string')
			if (containerClass is None or containerId is None):
				runtime.logger.report('Improper mapped container values.')
				return
		else:
			isRequired = data.get('isRequired', False)
			dataType = getDataType(runtime, data, transformName, transformFile)
			mappedValue = getAttribute(flatenedResult, mappingRule, dataType)
			if mappedValue is not None:
				mappedAttributes[name] = mappedValue
			else:
				## No value found...
				if isRequired is not None:
					## Value isn't required, continue parsing the next attribute
					continue
				else:
					## Transform file listed this as required; need to abort
					runtime.logger.report('No value found for attribute {name!r}; transform file {transformFile!r} listed this as required... skipping object creation.', name=name, transformFile=transformFile)
					return

	## Create the container first, if there is one
	if (containerId is not None):
		runtime.results.addObject(containerClass, uniqueId=containerId)

	## Create the target object
	objectId, exists = addObject(runtime, classToCreate, **mappedAttributes)
	## If we have a container, link the object to the container
	if containerId is not None:
		addLink(runtime, 'Enclosed', containerId, objectId)

	## Send results back 1 at a time, to avoid conflicts causing a DB rollback
	runtime.logger.report(' result to send: {result!r}', result=runtime.results.getJson())
	runtime.sendToKafka()

	## end startNormalization
	return
def trackCiToCreate(runtime, ipObjectId, ciSection, attributes):
    """Create the custom CI defined by the mapping definition."""
    ciType = ciSection.get('type')
    staticAttributes = ciSection.get('staticAttributes', {})
    ## Add any static attributes
    for attr, value in staticAttributes.items():
        if attr not in attributes:
            attributes[attr] = value.strip()
    runtime.logger.report(
        'trackCiToCreate: create attributes on {} CI: {}'.format(
            ciType, attributes))
    ## Create the object and link the IP
    objectId, exists = addObject(runtime, ciType, **attributes)
    addLink(runtime, 'Usage', objectId, ipObjectId)

    ## end trackCiToCreate
    return
def createObjects(runtime, output, processFile, nodeId, ipaddress, hostname, domain):
	"""Grouping two different send methods in this function.

	The first method formats the content as expected for our internal database,
	and either implicitely or explicitely sends it back to the framework. The
	second method formats it in another way and sends it to a different topic
	on the bus (Kafka), to be consumed by a external endpoint.
	"""
	## Create file objects in the format for the CMS to consume; these
	## objects are implicitely sent back after the startJob function returns
	## ===================================================================
	## Map properties from commands into attributes for the CMS object
	attributes = {}
	setAttribute(attributes, 'name', 'Python')
	setAttribute(attributes, 'version', output, 256)
	#setAttribute(attributes, 'recorded_by', 'shell_qualify_python', 256)
	setAttribute(attributes, 'recorded_by', __name__, 256)
	setAttribute(attributes, 'path', processFile, 256)

	## Create the software and link it to the node
	softwareId = addObject(runtime, 'SoftwarePackage', **attributes)
	addLink(runtime, 'Enclosed', nodeId, softwareId)

	## The above results are tracked by the runtime object, and returned
	## after the job finishes. Alternatively, you can explicitely send them
	## back by calling the sendToKafka function without any arguments:
	#runtime.sendToKafka()
	## But if you do that, make sure to put the node object back on for the
	## next SoftwarePackage object to be linked to the node object again:
	#runtime.results.addObject('Node', uniqueId=nodeId)
	## ===================================================================


	## Now send explicitely to a different kafka topic, using any format you
	## wish; illustrating streaming multiple outputs for different consumers
	## ===================================================================
	customFormat = {
		'hostname' : hostname,
		'domain' : domain,
		'ipaddress' : ipaddress,
		'software' : 'Python',
		'version' : output,
		'path' : processFile
	}
	runtime.sendToKafka('security', customFormat)
Ejemplo n.º 16
0
def createObjects(runtime, osType, osAttrDict, biosAttrDict, nameAttrDict,
                  ipAddresses, ipDict, endpoint, protocolReference):
    """Create objects and links in our results."""
    protocolId = None
    try:
        ## Log when the 'printDebug' parameter is set
        runtime.logger.report('osAttrDict  : {osAttrDict!r}',
                              osAttrDict=osAttrDict)
        runtime.logger.report('biosAttrDict: {biosAttrDict!r}',
                              biosAttrDict=biosAttrDict)
        runtime.logger.report('nameAttrDict  : {nameAttrDict!r}',
                              nameAttrDict=nameAttrDict)
        runtime.logger.report('ipAddresses : {ipAddresses!r}',
                              ipAddresses=ipAddresses)

        ## First create the node
        domain = nameAttrDict.get('domain')
        hostname = nameAttrDict.get('hostname')
        manufacturer = biosAttrDict.get('manufacturer')
        nodeAttributes = {}
        for thisAttr in ['distribution', 'platform', 'version', 'kernel']:
            thisValue = osAttrDict.get(thisAttr)
            if thisValue is not None:
                nodeAttributes[thisAttr] = thisValue
        nodeAttributes['hardware_provider'] = manufacturer
        nodeId = None
        if domain is None:
            nodeId, exists = addObject(runtime,
                                       osType,
                                       hostname=hostname,
                                       **nodeAttributes)
        else:
            nodeId, exists = addObject(runtime,
                                       osType,
                                       hostname=hostname,
                                       domain=domain,
                                       **nodeAttributes)

        ## Establish an FQDN string for local IP addresses (loopback)
        realm = runtime.jobMetaData.get('realm', 'NA')
        FQDN = 'NA'
        if hostname is not None:
            FQDN = hostname
            if (domain is not None and domain not in hostname):
                FQDN = '{}.{}'.format(hostname, domain)

        ## Now create the IPs
        trackedZones = {}
        for ip in ipAddresses:
            ipId = None
            if (ip in ['127.0.0.1', '::1', '0:0:0:0:0:0:0:1']):
                ## Override the realm setting for two reasons: we do not want these
                ## IPs in endpoint query results, and we want to track one per node
                ipId, exists = runtime.results.addIp(address=ip, realm=FQDN)
            else:
                ipId, exists = runtime.results.addIp(address=ip, realm=realm)

                ## Add any DNS records found
                if ip in ipDict:
                    for entry in ipDict[ip]:
                        (domainName, recordData) = entry
                        ## Create the zone if necessary
                        if domainName not in trackedZones:
                            ## Add the zone onto the result set
                            zoneId, exists = addObject(runtime,
                                                       'Domain',
                                                       name=domainName)
                            trackedZones[domainName] = zoneId
                        zoneId = trackedZones[domainName]
                        ## Create the DNS record
                        recordId, exists = addObject(runtime,
                                                     'NameRecord',
                                                     name=recordData,
                                                     value=ip)
                        addLink(runtime, 'Enclosed', zoneId, recordId)

            addLink(runtime, 'Usage', nodeId, ipId)
        ## In case the IP we've connected in on isn't in the IP table list:
        if endpoint not in ipAddresses:
            ipId, exists = addIp(runtime, address=endpoint)
            addLink(runtime, 'Usage', nodeId, ipId)

        ## Now create the SSH object
        protocolId, exists = addObject(runtime,
                                       'SSH',
                                       container=nodeId,
                                       ipaddress=endpoint,
                                       protocol_reference=protocolReference,
                                       realm=realm,
                                       node_type=osType)
        addLink(runtime, 'Enclosed', nodeId, protocolId)

        ## Now create the hardware
        serial_number = biosAttrDict.get('serial_number')
        bios_info = biosAttrDict.get('bios_info')
        model = biosAttrDict.get('model')
        manufacturer = biosAttrDict.get('manufacturer')
        uuid = biosAttrDict.get('uuid')
        if serial_number is not None:
            hardwareId, exists = addObject(runtime,
                                           'HardwareNode',
                                           serial_number=serial_number,
                                           bios_info=bios_info,
                                           model=model,
                                           vendor=manufacturer,
                                           uuid=uuid)
            addLink(runtime, 'Usage', nodeId, hardwareId)

        ## Update the runtime status to success
        runtime.status(1)

    except:
        runtime.setError(__name__)

    ## end createObjects
    return protocolId
def processResults(runtime, client, mappingEntries):
    """Get nodes & hardware objects passed in and check for matches."""
    try:
        ## Get node attributes coming in
        identifier = runtime.endpoint.get('identifier')
        node = runtime.endpoint.get('children').get('Node', [])[0]
        prevNodeData = node.get('data', {})
        nodeName = prevNodeData.get('hostname')
        nodeId = node.get('identifier')
        deviceOID = prevNodeData.get('snmp_oid')
        runtime.logger.report('Processing node {} with snmp_oid {}'.format(
            nodeName, deviceOID))
        if deviceOID is None:
            raise ValueError(
                'Node {} snmp_oid attribute is empty; cannot compare'.format(
                    nodeName))

        ## Get hardware attributes coming in
        hardware = None
        prevHardwareData = {}
        hardwareId = None
        nodeHardwareList = node.get('children').get('Hardware', [])
        if len(nodeHardwareList) > 0:
            hardware = nodeHardwareList[0]
            prevHardwareData = hardware.get('data', {})
            hardwareId = hardware.get('identifier')

        ## Dictionaries for our attribute-to-value mapping here
        newNodeData = {}
        newHardwareData = {}
        objectTypes = {}
        foundMatch = False

        ## Loop through the mapping entries
        for entry in mappingEntries:
            ref = entry.get('descriptor')
            matchingSection = entry.get('matchingSection', {})

            ## Matching section
            snmpOID = matchingSection.get('snmpOID')
            comparisonOperator = matchingSection.get('comparisonOperator')
            comparisonValue = matchingSection.get('comparisonValue')
            if comparisonOperator == '==':
                if deviceOID != snmpOID:
                    continue
            elif comparisonOperator.lower() == 'regex':
                escapedOID = snmpOID.replace('.', '[.]')
                value = comparisonValue.replace('snmpOID', escapedOID, re.I)
                if not re.search(value, deviceOID):
                    continue
            else:
                runtime.logger.warn(
                    'Unknown compare type for mapping {}. Received {} and expected either "==" or "regEx".'
                    .format(ref, comparisonOperator))
                continue

            foundMatch = True
            runtime.logger.report(' Matched section: {}'.format(ref))

            ## Mapping section
            mappingSection = entry.get('mappingSection', {})
            processThisMappingSection(runtime, client, mappingSection,
                                      objectTypes, prevNodeData,
                                      prevHardwareData, newNodeData,
                                      newHardwareData)

            ## We already matched
            break

        if foundMatch:
            ## Update the objects/links
            thisNode = None
            thisHardware = None
            if len(newNodeData) > 0:
                ## Update the node
                thisNode, exists = addObject(runtime,
                                             'Node',
                                             uniqueId=nodeId,
                                             **newNodeData)
            if len(newHardwareData) > 0:
                if hardwareId is None:
                    ## Create a new hardware object
                    thisHardware, exists = addObject(
                        runtime, objectTypes.get('hardware', 'Hardware'),
                        **newHardwareData)
                else:
                    ## Update the previous hardware
                    thisHardware, exists = addObject(
                        runtime,
                        objectTypes.get('Hardware'),
                        uniqueId=hardwareId,
                        **newHardwareData)
                addLink(runtime, 'Usage', thisNode, thisHardware)

        else:
            runtime.logger.report(
                'No match found on node {} with snmp_oid {}'.format(
                    nodeName, deviceOID))
            runtime.setInfo(
                'No match found on node {} with snmp_oid {}'.format(
                    nodeName, deviceOID))

    except:
        runtime.setError(__name__)

    ## end processResults
    return
Ejemplo n.º 18
0
def createObjects(runtime, osAttrDict, biosAttrDict, csAttrDict, ipAddresses,
                  endpoint, protocolId):
    """Create objects and links in our results."""
    try:
        ## First create the node
        domain = csAttrDict.get('Domain', None)
        hostname = csAttrDict.get('Name', None)
        vendor = osAttrDict.get('Manufacturer', None)
        platform = osAttrDict.get('Caption', None)
        version = osAttrDict.get('Version', None)
        hw_provider = csAttrDict.get('Manufacturer', None)
        nodeId, exists = addObject(runtime,
                                   'Node',
                                   hostname=hostname,
                                   domain=domain,
                                   vendor=vendor,
                                   platform=platform,
                                   version=version,
                                   hardware_provider=hw_provider)

        ## Now create the IPs
        for ip in ipAddresses:
            with suppress(ValueError):
                ipId, exists = addIp(runtime, address=ip)
                addLink(runtime, 'Usage', nodeId, ipId)
        ## In case the IP we've connected in on isn't in the IP table list:
        if endpoint not in ipAddresses:
            with suppress(ValueError):
                ipId, exists = addIp(runtime, address=endpoint)
                addLink(runtime, 'Usage', nodeId, ipId)

        ## Now create the WMI object
        realm = runtime.jobMetaData.get('realm')
        snmpId, exists = addObject(runtime,
                                   'WMI',
                                   container=nodeId,
                                   ipaddress=endpoint,
                                   protocol_reference=protocolId,
                                   realm=realm,
                                   node_type='Windows')
        addLink(runtime, 'Enclosed', nodeId, snmpId)

        ## Now create the hardware
        serial_number = biosAttrDict.get('SerialNumber', None)
        bios_info = biosAttrDict.get('Caption', None)
        model = csAttrDict.get('Model', None)
        manufacturer = csAttrDict.get('Manufacturer', None)
        hardwareId, exists = addObject(runtime,
                                       'HardwareNode',
                                       serial_number=serial_number,
                                       bios_info=bios_info,
                                       model=model,
                                       vendor=manufacturer)
        addLink(runtime, 'Usage', nodeId, hardwareId)

        ## Update the runtime status to success
        runtime.status(1)

    except:
        runtime.setError(__name__)

    ## end createObjects
    return