def process(self, context): descriptor = context.application.getApplicationComponent( ).getExplicitPluginById(ConfigurationFilesPlugin.PLUGIN_ID) if not descriptor: return element = descriptor.getRootElement() configElements = element.getChildren( ConfigurationFilesPlugin.ELEMENT_CONFIG_FILE) # parse DOM paths = ifilter(None, imap(self._getLocationFromElement, configElements)) # evaluate expressions parseRuleContexts = context.application.getParseRuleContexts() parseFn = fptools.partiallyApply(self._parseLocation, fptools._, parseRuleContexts) parsedPaths = ifilter(None, imap(parseFn, paths)) # retrieve content fileSystem = file_system.createFileSystem(context.client) retrieveFn = fptools.partiallyApply(self._retrieveConfigFile, fptools._, fileSystem) configFiles = ifilter(None, imap(retrieveFn, parsedPaths)) # report builder = file_topology.Builder() reporter = file_topology.Reporter(builder) reportFn = fptools.partiallyApply(self._reportConfigFile, fptools._, reporter, context) oshs = ifilter(None, imap(reportFn, configFiles)) for osh in oshs: context.resultsVector.add(osh)
def _reportDevComponentsAsConfigFile(interfaces, libraries, services, clusterOsh): r'@types: list, list, list, list, osh -> oshv' # report as repository file fileReporter = file_topology.Reporter(file_topology.Builder()) Registry = SystemComponentRegistryFileComposer.Registry fileComposer = SystemComponentRegistryFileComposer() vector = ObjectStateHolderVector() if interfaces: vector.add(fileReporter.report( fileComposer.composeFile(Registry('interfaces', interfaces)), clusterOsh)) if libraries: vector.add(fileReporter.report( fileComposer.composeFile(Registry('libraries', libraries)), clusterOsh)) if services: vector.add(fileReporter.report( fileComposer.composeFile(Registry('services', services)), clusterOsh)) return vector
def _report_inst_profile_file(file_, host_osh, inst_osh): '@types: File, Address, osh -> osh, list[osh]' reporter = file_topology.Reporter(file_topology.Builder()) file_osh = reporter.report(file_, host_osh) usage_osh = sap.LinkReporter().reportUsage(inst_osh, file_osh) return file_osh, [file_osh, usage_osh]
def process(self, context): r''' @types: applications.ApplicationSignatureContext ''' # ------------------------------------------------------------ DISCOVERY "SAP TREX plug-in DISCOVERY start" | info shell = context.client fs = file_system.createFileSystem(shell) pathtools = file_system.getPath(fs) # x) get process related application hostOsh = context.hostOsh application = context.application destinationIp = application.getConnectionIp() "x) Find TREX Daemon process that has profile path as parameter" | info mainProcess = findFirst(isMainTrexProcess, context.application.getProcesses()) profilePath = sap_discoverer.getProfilePathFromCommandline( mainProcess.commandLine) "x) Read profile content: %s" % profilePath | info getFileContent = Sfn( Fn(self.__getFileWithContent, shell, pathtools, __)) profileFile = profilePath and getFileContent(profilePath) if not profileFile: "Plug-in flow broken. Failed to read instance profile\ content based on path from the TREXDaemon command line" | warn return "x) Instance profile parsing" | info sapIniParser = sap_discoverer.IniParser() instanceProfileParser = sap_discoverer.InstanceProfileParser( sapIniParser) defaultProfileParser = sap_trex_discoverer.DefaultProfileParser( sapIniParser) try: resultAsIni = instanceProfileParser.parseAsIniResult( profileFile.content) instanceProfile = instanceProfileParser.parse(resultAsIni) defaultProfile = defaultProfileParser.parse(resultAsIni) except Exception: logger.warnException("Failed to parse instance profile") return rfcConfigs = [] trexSystem = defaultProfile.getSystem() trexInstance = instanceProfile.getInstance() trexInstanceName = trexInstance.getName() + trexInstance.getNumber() isBiaProduct = 0 versionInfo = None # # master by default, if topology file is not found that means # # that current one is the only instance # isMaster = 1 trexTopology = None "x) Initialize TREX instance layout" | debug systemName = trexSystem.getName() systemBasePath = sap_discoverer.findSystemBasePath( mainProcess.getExecutablePath(), systemName) if systemBasePath: systemLayout = sap_trex_discoverer.SystemLayout( pathtools, systemBasePath, systemName) 'System path: %s' % systemLayout.getRootPath() | info instancePath = systemLayout.composeInstanceDirPath( trexInstanceName) 'Instance path: %s' % instancePath | debug instanceLayout = sap_trex_discoverer.InstanceLayout( pathtools, instancePath, trexInstanceName) "x) Get content of default profile as it contains information about product" "x) Determine whether we deal with BIA based on version information" | debug defaultProfilePath = systemLayout.getDefaultProfileFilePath() defaultProfileFile = getFileContent(defaultProfilePath) try: resultAsIni = instanceProfileParser.parseAsIniResult( defaultProfileFile.content) defaultProfile = defaultProfileParser.parse(resultAsIni) except Exception: logger.warnException("Failed to parse default profile") else: isBiaProduct = defaultProfile.getProductType( ) == sap_trex.Product.BIA (isBiaProduct and "BIA" or "non-BIA", "product detected") | info # get instance host name from profile name instanceHostname = None try: destinationSystem = sap_discoverer.parseSapSystemFromInstanceProfileName( profileFile.getName()) except Exception: msg = "Failed to parse instance hostname from profile file name" logger.debugException(msg) else: instanceHostname = first( destinationSystem.getInstances()).getHostname() "x) Discover whole topology from (topology.ini)" | info # topology.ini file location and format differs depending on the # product: # -a) BIA (has plain-ini file at <SID>/sys/global/trex/data/topology.ini # -b) TREX (has several places where topology.ini can be stored) discoverTopologyIniFilePath = fptools.safeFunc( sap_trex_discoverer.discoverTopologyIniFilePath) topologyFilePath = (isBiaProduct and systemLayout.getTopologyIniPath() or discoverTopologyIniFilePath( fs, instanceLayout, instanceHostname)) topologyFile = topologyFilePath and getFileContent( topologyFilePath) if topologyFile: try: configParser = sap_trex_discoverer.TopologyConfigParser() trexTopology = sap_trex_discoverer.TrexTopologyConfig( configParser.parse(topologyFile.content)) # find instance between master end-points # landscapeSnapshot = topology.getGlobals().getLandscapeSnapshot() # masterEndpoints = landscapeSnapshot.getMasterEndpoints() # activeMasterEndpoints = landscapeSnapshot.getActiveMasterEndpoints() # topologyNodes = topology.getHostNodes() ## # isEndpointWithInstanceHostname = (lambda # ep, hostname = instanceHostname: ep.getAddress() == hostname) # isMaster = len(filter(isEndpointWithInstanceHostname, # landscapeSnapshot.getMasterEndpoints())) # "host role is %s" % (isMaster and "master" or "slave") | info except: logger.warnException( "Failed to parse topology configuration") else: logger.warn( "Failed to get content for the topology configuration") "x) Discover TREX version information from saptrexmanifest.mf" | info # read version info from manifest file manifestFile = getFileContent(instanceLayout.getManifestFilePath()) if manifestFile: manifestParser = sap_trex_discoverer.SapTrexManifestParser( sapIniParser) versionInfo = manifestParser.parseVersion(manifestFile.content) else: 'Failed to discover version from manifest file' | warn 'Second attept to get version from updateConfig.ini file' | info profileSystem = Sfn( sap_discoverer.parseSapSystemFromInstanceProfileName)( profileFile.getName()) if profileSystem: hostname = first( profileSystem.getInstances()).getHostname() updateConfigFile = getFileContent( instanceLayout.composeUpdateConfigIniFilePath( hostname)) versionInfo = updateConfigFile and sap.VersionInfo( updateConfigFile.content.strip()) "x) Discover served systems ( in case if RFC configuration established )" | info rfcServerIniFilePath = ( isBiaProduct and systemLayout.getRfcServerConfigFilePath() or instanceLayout.composeTrexRfcServerIniFilePath( instanceHostname)) rfcServerIniFile = getFileContent(rfcServerIniFilePath) if rfcServerIniFile: rfcConfigs = filter(None, (fptools.safeFunc( sap_trex_discoverer.parseConnectionsInRfcServerIni)( rfcServerIniFile.content))) # -------------------------------------------------------- REPORTING "SAP TREX plug-in REPORTING start" | info trexOsh = application.getOsh() vector = context.resultsVector configFileReporter = file_topology.Reporter(file_topology.Builder()) trexReporter = sap_trex.Reporter(sap_trex.Builder()) linkReporter = sap.LinkReporter() softwareBuilder = sap.SoftwareBuilder() "x) - report profile content as configuration document for the application" | info vector.add(configFileReporter.report(profileFile, trexOsh)) ("x) - report %s" % trexSystem) | info trexSystemOsh = trexReporter.reportSystem(trexSystem) vector.add(trexSystemOsh) vector.add(linkReporter.reportMembership(trexSystemOsh, trexOsh)) "x) - report instance name and version" | info softwareBuilder.updateName(trexOsh, trexInstanceName) "x) report instance number: %s" % trexInstance.getNumber() | info instanceBuilder = sap_trex.Builder() instanceBuilder.updateInstanceNumber(trexOsh, trexInstance.getNumber()) if versionInfo: softwareBuilder.updateVersionInfo(trexOsh, versionInfo) if isBiaProduct: softwareBuilder.updateDiscoveredProductName( trexOsh, sap_trex.Product.BIA.instanceProductName) "x) report RFC connections" | info dnsResolver = netutils.DnsResolverByShell(shell, destinationIp) vector.addAll(reportRfcConfigs(rfcConfigs, dnsResolver, hostOsh)) "x) report all topology nodes" | info if trexTopology: reportHostNode = fptools.partiallyApply(reportTrexHostNode, fptools._, trexTopology, isBiaProduct) vectors = map(reportHostNode, trexTopology.getHostNodes()) fptools.each(vector.addAll, vectors)
def process(self, context): r''' @types: applications.ApplicationSignatureContext ''' # ==================== DISCOVERY shell = context.client fs = file_system.createFileSystem(shell) pathtools = file_system.getPath(fs) # 1) get process related application application = context.application connectionIp = application.getConnectionIp() # 2) find out process where path to the instance profile is stored logger.info(" Get executable path of main process ") mainProcess = application.getMainProcesses()[0] # 3) logger.info("Found out path to instance profile") instanceProfilePath = self.__getProfilePath(mainProcess) # 4) logger.info("Instance profile path: ", instanceProfilePath, ". Get content") getContent = fptools.safeFunc(self.__getContent, Exception) profileFile = (instanceProfilePath and getContent(shell, pathtools, instanceProfilePath)) if not profileFile: logger.warn("Failed to get content of instance profile") return # 5) parse content using instance and default profile parsers logger.info("Make configuration parsing") iniParser = sap_discoverer.IniParser() instancePfParser = sap_discoverer.InstanceProfileParser(iniParser) try: instanceProfile = instancePfParser.parseContent( profileFile.content) except Exception: logger.warnException("Failed to parse instance profile") else: traceConfig = None runtimeConfig = None sapInstance = instanceProfile.instance sapInstance = sap.Instance(sapInstance.name + sapInstance.number, sapInstance.number, sapInstance.hostname) # 6) Process runtime.properties that contains information about # Solution Manager and SLD if present logger.info("Create agent layout") logger.info("Get content of runtime properties") agentLayout = fptools.safeFunc( sap_smd_discoverer.createAgentLayoutFromBinPath)( (pathtools.isAbsolute(mainProcess.executablePath) and mainProcess.executablePath or discoverExecutablePath(shell, mainProcess)), fs, pathtools) if agentLayout: propertiesFile = getContent( shell, pathtools, agentLayout.getRuntimePropertiesPath()) if propertiesFile: parser = sap_smd_discoverer.RuntimePropertiesParser( sap_discoverer.IniParser()) try: runtimeConfig = parser.parse(propertiesFile.content) except Exception: logger.warnException( "Failed to parse runtime properties") logger.info("Find out version information") devSmdAgentFile = getContent( shell, pathtools, agentLayout.getDevSmdAgentConfigFile()) if devSmdAgentFile: configParser = sap_smd_discoverer.DevSmdAgentConfigParser() # find config with corresponding PID (of main process) hasMainProcessPid = lambda c, pid=mainProcess.getPid( ): c.pid == pid traceConfig = fptools.findFirst( hasMainProcessPid, configParser.parse(devSmdAgentFile.content)) if not traceConfig: logger.warn( "Failed to find trace information for the main process" ) # === REPORT === smdAgentOsh = application.getOsh() vector = context.resultsVector endpointReporter = netutils.EndpointReporter( netutils.ServiceEndpointBuilder()) configFileReporter = file_topology.Reporter( file_topology.Builder()) linkReporter = sap.LinkReporter() smdAgentBuilder = sap_smd.Builder() softwareBuilder = sap.SoftwareBuilder() softwareReporter = sap.SoftwareReporter(sap.SoftwareBuilder()) resolverByShell = netutils.DnsResolverByShell(shell) processOsh = mainProcess.getOsh() # x) update name of application using instance name softwareBuilder.updateName(smdAgentOsh, sapInstance.getName()) # x) configuration files related to running_software vector.add(configFileReporter.report(profileFile, smdAgentOsh)) if traceConfig: # x) update version information in application smdAgentOsh = softwareBuilder.updateVersionInfo( smdAgentOsh, traceConfig.versionInfo) if traceConfig.jstartVersionInfo: smdAgentOsh = smdAgentBuilder.updateJstartVersionInfo( smdAgentOsh, traceConfig.jstartVersionInfo) # x) show relation between agent and # - SMD server / no enough information / # - message server of SCS OR Solution Manager, represented as agent connection endpoint # - SLD if propertiesFile and runtimeConfig: # x) report properties file as configuration document vector.add( configFileReporter.report(propertiesFile, smdAgentOsh)) # x) Report relation between agent and SLD server and SolMan # Resolve endpoint addresses # make function that will accept endpoint only resolveEndpointFn = fptools.partiallyApply( self.__resolveEndpointAddress, fptools.safeFunc(resolverByShell.resolveIpsByHostname, []), fptools._) # - SLD relation if runtimeConfig.sldEndpoint: for endpoint in resolveEndpointFn( runtimeConfig.sldEndpoint): sldHostOsh = endpointReporter.reportHostFromEndpoint( endpoint) vector.add(sldHostOsh) sldEndpointOsh = endpointReporter.reportEndpoint( endpoint, sldHostOsh) vector.add(sldEndpointOsh) # this unknown server type must be SLD server sldOsh = softwareReporter.reportUknownSoftware( sldHostOsh) vector.add(sldOsh) vector.add( linkReporter.reportUsage(sldOsh, sldEndpointOsh)) # report link between process and SLD server endpoint vector.add( linkReporter.reportClientServerRelation( processOsh, sldEndpointOsh)) # - Solution Manager relation agentConnectionEndpoint = runtimeConfig.getAgentConnecitonEndpoint( ) if agentConnectionEndpoint: for endpoint in resolveEndpointFn(agentConnectionEndpoint): hostOsh = endpointReporter.reportHostFromEndpoint( endpoint) vector.add(hostOsh) endpointOsh = endpointReporter.reportEndpoint( endpoint, hostOsh) vector.add(endpointOsh) softwareOsh = softwareReporter.reportUknownSoftware( hostOsh) vector.add(softwareOsh) vector.add( linkReporter.reportUsage(softwareOsh, endpointOsh)) # report link between process and SolMan end-point vector.add( linkReporter.reportClientServerRelation( processOsh, endpointOsh))
def _reportPfFile(pfFile, applicationOsh): #x) report profile content as configuration document for the application logger.debug("Report instance profile as configuration document") fileReporter = file_topology.Reporter(file_topology.Builder()) return fileReporter.report(pfFile, applicationOsh)