def get_process_executable_path(shell, pf_path, process, system): ''' Get process executable path @types: shellutils.Shell, str, process.Process, sap.System ''' sys_name = system.getName() root_path = sap_discoverer.findSystemBasePath(pf_path, sys_name) inst_name = None if system.getInstances(): inst = system.getInstances()[0] inst_name = '%s%s' % (inst.getName(), inst.getNumber()) return get_process_bin_path(shell, process, root_path, inst_name)
def _discover_msg_hostname(shell, pf_path): r'''Read DEFAULT profile to get message server hostname as usually this information resides there @types: Shell, str -> str?''' fs = file_system.createFileSystem(shell) pathtools = file_system.getPath(fs) system, _ = sap_discoverer.parsePfDetailsFromPath(pf_path) rootPath = sap_discoverer.findSystemBasePath(pf_path, system.getName()) layout = sap_discoverer.Layout(pathtools, rootPath) default_pf_path = layout.getDefaultProfileFilePath() try: content = shell.safecat(default_pf_path) except (JException, Exception), e: logger.warn("Failed to get profile content: %s" % e)
def discover_default_pf(shell, pf_path, system_name): ''' Discover DEFAULT.PFL for particular system based on any profile path of this system. @return: pair of profile path and its parsed content @types: shellutils.Shell, str, str -> (File?, sap_discoverer.IniDocument?) ''' _info = (system_name, pf_path) logger.info("Discover DEFAULT.pl for %s system based on %s" % _info) pathtool = file_system.getPathToolByShell(shell) root_path = sap_discoverer.findSystemBasePath(pf_path, system_name) sys_layout = sap_discoverer.Layout(pathtool, root_path, system_name) default_pf_path = sys_layout.getDefaultProfileFilePath() logger.info("Default profile path found: %s" % default_pf_path) return read_pf(shell, default_pf_path)
def _get_pf_doc(self, pf_path, sys_name, shell): '@types: str, str, Shell -> File, File, InitDocument' base_path = sap_discoverer.findSystemBasePath(pf_path, sys_name) get_def_pf_fn = Fn(discover_default_pf, shell, pf_path, sys_name) get_inst_pf_fn = Fn(sap_discoverer_by_shell.read_pf, shell, pf_path) default_pf_result = self._get_or_discover(base_path, Sfn(get_def_pf_fn)) default_pf_file, default_pf_doc = default_pf_result or (None, None) if not default_pf_file: logger.warn("Failed to get content for the DEFAULT.PFL") pf_file, pf_doc = self._get_or_discover(pf_path, Sfn(get_inst_pf_fn)) if not pf_file: logger.warn("Failed to get content for the instance profile") doc = sap_discoverer.createPfsIniDoc(default_pf_doc, None, pf_doc) return default_pf_file, pf_file, doc
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 "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)