def _discoverAscsInPf(doc, system, system_osh, oshPerInstance): enque_host, enque_instance_nr = AscsInfoPfParser.parse(doc) #Change implemented within the scope of issue "QCIM1H96235 Job ABAP Topology discovers Central Services related to wrong SAP System" #In case an application server is being reinstalled and / or switched to a new SAP System we can not trust data in UCMDB as for SAP SYSTEM NAME #And must check if this data in trigger coincides to the one on profile, in case it's not true - STOP the discovery with ERROR and REPORT NOTHING. #Valid data will be reported from a new trigger with new valid SAP SYSTEM NAME system_name = doc.get('SAPSYSTEMNAME') if system_name and system and system_name.upper().strip() != system.getName().upper().strip(): logger.error('Trigger data and destination SAP System name are not equal. Stopping discovery.') raise SapSystemInconsistentDataException('SAP System name is miss-matched in trigger and destination') if enque_host: logger.info("Found ASCS: %s %s" % (enque_host, enque_instance_nr)) instance = sap.Instance('ASCS', enque_instance_nr, enque_host) # create ASCS instance with membership ascs_osh, vector = _report_ascs_osh(enque_host, enque_instance_nr, system) if ascs_osh: vector.add(sap.LinkReporter().reportMembership(system_osh, ascs_osh)) for _, inst_osh in oshPerInstance.iteritems(): vector.add(sap.LinkReporter().reportMembership(system_osh, inst_osh)) return vector else: return None else: return None
def reportBareSapInstByEndpoints(endpoints, inst, system, sapOsh): r''' Use gateway information to report bare sap application server. Gateway usually is started with some instance and has the same coordinates (SID, instance_nr) Reported instance is bare due to the fact we don't know it's type: JAVA, ABAP, SCS, CI @types: list[netutils.Endpoint], Instance, System, osh -> oshv''' hostOsh, endpointOshs, oshs = _reportHostByEndpoints(endpoints) linkReporter = sap.LinkReporter(sap.LinkBuilder()) builder = sap.GeneralInstanceBuilder(reportName=False, reportInstName=False) sapServerReporter = sap.GeneralInstanceReporter(builder) # anonymous instance instOsh = sapServerReporter.reportInstance(inst, system, hostOsh) oshs.append(instOsh) # usage link between appserver and endpoints oshs.extend(linkReporter.reportUsage(instOsh, osh) for osh in endpointOshs) # DO NOT report membership between system and gateway # Explanation: # sometimes you can discover systems that don't have relationship to current host. # This can lead to incorrect merging of to systems (inside OSH vector) # systemOsh = trexReporter.reportSystem(system) # vector.add(systemOsh) # oshs.append(linkReporter.reportMembership(sapOsh, instOsh)) return oshs
def report_system(self, system, osh): '@types: System, osh -> osh, list[osh]' reporter = sap.Reporter(sap.Builder()) linkReporter = sap.LinkReporter() system_osh = reporter.reportSystem(system) memb_osh = linkReporter.reportMembership(system_osh, osh) return system_osh, [system_osh, memb_osh]
def report_system(self, system, osh): '@types: System, osh -> osh, list[osh]' system_osh, cluster_osh, vector = reportSapSystem(system) linkReporter = sap.LinkReporter() vector.add(linkReporter.reportMembership(cluster_osh, osh)) vector.add(linkReporter.reportMembership(system_osh, osh)) return system_osh, list(vector)
def discoverAllInstances(client, config): r''' Can be only applied for discovery by JMX due to deserialization limitatations of WebServices client @types: BaseSapJmxClient, DiscoveryConfig -> oshv''' discoverer = sap_jee_discoverer.ClusterDiscoverer(client) clusterInfo = discoverer.getClusterInfo() cluster = clusterInfo.cluster instances = clusterInfo.instances system = sap.System(cluster.getName()) systemOsh, clusterOsh, vector = _reportSapSystem(system) linkReporter = sap.LinkReporter() ipsPerInst = zip(map(_resolveInstInfoHostname, instances), instances) hasResolvedIps = first endReporter = netutils.EndpointReporter(netutils.ServiceEndpointBuilder()) for ips, instInfo in filter(hasResolvedIps, ipsPerInst): inst = instInfo.instance instOsh, hostOsh, iVector = reportInst(inst, system, systemOsh, clusterOsh, ips, reportInstName=True) vector.addAll(iVector) resolve = sap_jee_discoverer._resolvedEndpointAddress for endp in flatten(keep(resolve, instInfo.endpoints)): endpOsh = endReporter.reportEndpoint(endp, hostOsh) vector.add(endpOsh) vector.add(linkReporter.reportUsage(instOsh, endpOsh)) return vector
def _reportJavaServer(inst, system, isScs, hostOsh, systemOsh): ''' @types: Instance, System, bool, osh, osh -> oshv ''' vector = ObjectStateHolderVector() reportInstName = False clusterOsh = sap_jee.reportClusterOnSystem(system, systemOsh) reporter, pdo = None, None if not isScs: builder = sap_jee.InstanceBuilder(reportInstName=reportInstName) reporter = sap_jee.InstanceReporter(builder) pdo = sap_jee.InstanceBuilder.InstancePdo(inst, system) else: builder = sap_jee.ScsInstanceBuilder(reportInstName=reportInstName) reporter = sap_jee.InstanceReporter(builder) pdo = sap_jee.InstanceBuilder.InstancePdo(inst, system) instOsh = reporter.reportInstancePdo(pdo, hostOsh) vector.add(instOsh) linkReporter = sap.LinkReporter() vector.add(linkReporter.reportMembership(clusterOsh, instOsh)) vector.add(linkReporter.reportMembership(systemOsh, instOsh)) return vector
def _reportRfc(instNr, sapOsh, hostOsh): '@types: str, osh, osh -> list[osh]' oshs = [] linkReporter = sap.LinkReporter(sap.LinkBuilder()) rfcType = sap.RfcConnectionTypeEnum.TCP_IP program = "" rfc = sap.LinkBuilder.RfcConnection(rfcType, instNr, program) oshs.append(linkReporter.reportRfcConnection(rfc, sapOsh, hostOsh)) return oshs
def _reportSystems(servedSystems, processOsh, shell, connectionIp, applicationOsh=None): resolveEndpoint = _getEndpResolveFn(shell, connectionIp) vector = ObjectStateHolderVector() softwareBuilder = sap.SoftwareBuilder() softwareReporter = sap.SoftwareReporter(softwareBuilder) linkR = sap.LinkReporter() #x) report details of served systems and relation with web-dispatcher for servedSystem in servedSystems: # report endpoints of external servers endpoints = servedSystem.getExternalServersEndpoints() endpoints = flatten(keep(resolveEndpoint, endpoints)) results = (_reportServerEndp(e, processOsh, applicationOsh) for e in endpoints) vector.addAll(map(third, results)) # report message server endpoint (metadata-source) # and application servers of served system sources = servedSystem.getMetadataSources() msgSources, sources = partition(isMessageServerSource, sources) logger.debug("Report %s msg sources" % len(msgSources)) logger.debug("Report %s other sources" % len(sources)) # process message server, report message server endpoints = keep(sap_webdisp.HasEndpoint.getEndpoint, msgSources) msgBuilder = sap.MessageServerBuilder() msgReporter = sap.CentralComponentReporter(msgBuilder) for e in flatten(keep(resolveEndpoint, endpoints)): e = netutils.createTcpEndpoint(e.getAddress(), e.getPort()) endpOsh, hostOsh, eVector = _reportServerEndp(e, processOsh) vector.addAll(eVector) msgOsh = msgReporter.reportAnonymous(hostOsh) vector.add(msgOsh) vector.add(linkR.reportUsage(msgOsh, endpOsh)) # process non message server sources sources = ifilter(isSourceWithEndpoint, sources) endpoints = keep(sap_webdisp.HasEndpoint.getEndpoint, sources) endpoints.extend(servedSystem.getApplicationServersEndpoints()) endpoints = flatten(keep(resolveEndpoint, endpoints)) for result in (_reportServerEndp(e, processOsh) for e in endpoints): endpOsh, hostOsh, eVector = result vector.addAll(eVector) appServerOsh = softwareReporter.reportUknownSoftware(hostOsh) vector.add(appServerOsh) vector.add(linkR.reportUsage(appServerOsh, endpOsh)) return vector
def _discoverInstanceDetails(client, baseTopology): r'@types: BaseSapJmxClient, str, System, osh, osh -> oshv' system, hostname, clusterOSH, systemOsh = baseTopology inst, servers = ServerProcessQuery().getSystemDetails(client) if not inst.hostname and hostname: inst = sap.Instance.replaceHostname(inst, hostname) instanceReporter = sap_jee.InstanceReporter(sap_jee.InstanceBuilder()) # report host by resolved IPs hostname = inst.hostname if not hostname: logger.warn("Failed to determine hostname for %s" % inst) return ObjectStateHolderVector() dnsResolver = netutils.JavaDnsResolver() vector = ObjectStateHolderVector() try: ips = dnsResolver.resolveIpsByHostname(hostname) except netutils.ResolveException: logger.warn("Failed to resolve hostname of %s" % inst) else: hostReporter = sap.HostReporter(sap.HostBuilder()) hostOSH, vector = hostReporter.reportHostWithIps(*ips) # report instance pdo = sap_jee.InstanceBuilder.InstancePdo(inst, system) instOsh = instanceReporter.reportInstancePdo(pdo, hostOSH) vector.add(instOsh) #report sap system systemOsh.setStringAttribute('data_note', 'This SAP System link to ' + hostOSH.getAttributeValue('host_key')) vector.add(systemOsh) # report j2ee_cluster -membership-> sap_app_server linkReporter = sap.LinkReporter() vector.add(linkReporter.reportMembership(clusterOSH, instOsh)) vector.add(linkReporter.reportMembership(systemOsh, instOsh)) # report server processes oshs = [_reportServerProcess(s, inst, instOsh) for s in servers] each(vector.add, oshs) # discover applications serverToOshs = filter(comp(_isWorkerProcess, first), zip(servers, oshs)) for server, osh in serverToOshs: id_ = server.id appNameToOsh = Sf(discoverEjbApplications)(client, id_, osh, clusterOSH, vector) Sf(buildWebApplications)(client, id_, osh, clusterOSH, appNameToOsh, vector) return vector
def _reportGatewayTopology(ips, port, clientOsh): '@types: list[_BaseIP], str, osh -> list[osh]' oshs = [] linker = sap.LinkReporter() hostReporter = sap.HostReporter(sap.HostBuilder()) hostOsh, vector = hostReporter.reportHostWithIps(*ips) oshs.extend([osh for osh in vector.iterator()]) gtwOsh = _reportAnonymouseGateway(hostOsh) oshs.append(gtwOsh) oshs.append(hostOsh) for ip in ips: endpointOsh = _reportGatewayEndpoint(ip, port, hostOsh) oshs.append(linker.reportClientServerRelation(clientOsh, endpointOsh)) oshs.append(linker.reportUsage(gtwOsh, endpointOsh)) return oshs
def _reportServerEndp(endpoint, processOsh, applicationOsh=None): vector = ObjectStateHolderVector() builder = netutils.ServiceEndpointBuilder() endpointReporter = netutils.EndpointReporter(builder) linkR = sap.LinkReporter() hostOsh = endpointReporter.reportHostFromEndpoint(endpoint) endpOsh = endpointReporter.reportEndpoint(endpoint, hostOsh) vector.add(hostOsh) vector.add(endpOsh) # client-server link with dispatcher process vector.add(linkR.reportClientServerRelation(processOsh, endpOsh)) if applicationOsh: vector.add(linkR.reportClientServerRelation(applicationOsh, endpOsh)) return endpOsh, hostOsh, vector
def _reportWdEndpoints(instPf, serverOsh, shell, connectionIp): #x) report end-points of web-dispatcher itself and resolve them dispatcherEndpoints = instPf.getDispatcherEndpoints() resolveEndpointAddress = _getEndpResolveFn(shell, connectionIp) endpoints = flatten(keep(resolveEndpointAddress, dispatcherEndpoints)) vector = ObjectStateHolderVector() builder = netutils.ServiceEndpointBuilder() endpointReporter = netutils.EndpointReporter(builder) linkReporter = sap.LinkReporter() for endpoint in endpoints: hostOsh = endpointReporter.reportHostFromEndpoint(endpoint) vector.add(hostOsh) endpointOsh = endpointReporter.reportEndpoint(endpoint, hostOsh) vector.add(endpointOsh) vector.add(linkReporter.reportUsage(serverOsh, endpointOsh)) return vector
def reportScsBasedOnMsgPort(system, hostname, msgEndpoints, systemOsh, clusterOsh, enqEndpoints=(), reportName=False): r''' @param reportName: influence on `name` attribute reporting. In some cases composite name attribute may contain not correct host information that has impact on reconciliation. Better do not report data we are not sure @types: sap.System, str, list[Endpoint], osh, list[Endpoint], bool -> oshv ''' vector = ObjectStateHolderVector() if not msgEndpoints: logger.warn("Failed to discover SCS - no message server information") return vector ips = (map(netutils.Endpoint.getAddress, msgEndpoints) + map(netutils.Endpoint.getAddress, enqEndpoints)) hostReporter = sap.HostReporter(sap.HostBuilder()) hostOsh, hVector = hostReporter.reportHostWithIps(*ips) vector.addAll(hVector) systemOsh.setStringAttribute('data_note', 'This SAP System link to ' + hostOsh.getAttributeValue('host_key')) vector.add(systemOsh) instIp = sap.createIp(first(ips)) msgEndpoint = first(msgEndpoints) number = sap_discoverer.parseInstNrInMsgServerPort(msgEndpoint.getPort()) inst = sap.Instance('SCS', number, hostname=hostname) pdo = sap_jee.InstanceBuilder.InstancePdo(inst, system, ipAddress=instIp) scsBuilder = sap_jee.ScsInstanceBuilder(reportName=reportName) instReporter = sap_jee.InstanceReporter(scsBuilder) instOsh = instReporter.reportInstancePdo(pdo, hostOsh) vector.add(instOsh) linkReporter = sap.LinkReporter() vector.add(linkReporter.reportMembership(clusterOsh, instOsh)) vector.add(linkReporter.reportMembership(systemOsh, instOsh)) for endpoint in (msgEndpoints + enqEndpoints): _, eVector = sap._reportEndpointLinkedToSoftware(endpoint, hostOsh, instOsh) vector.addAll(eVector) return vector
def reportInstanceWithSystem(instance_info, ips, system, systemp_osh, client_number=None, application_ip=None, cred_id=None): if cred_id: logger.info("Credentials are set on %s" % str(instance_info.instance)) linkReporter = sap.LinkReporter(sap.LinkBuilder()) server_osh, vector = reportInstanceInfo( instance_info, ips, system, credsId=cred_id, connectionClientNr=client_number, application_ip=first(instance_info.host.address.ips), system_osh=systemp_osh) vector.add(linkReporter.reportMembership(systemp_osh, server_osh)) return server_osh, vector
def _reportAbapServer(inst, system, isScs, hostOsh, systemOsh): ''' @types: Instance, System, bool, osh, osh -> oshv ''' vector = ObjectStateHolderVector() reportInstName = False reporter, pdo = None, None if not isScs: builder = sap_abap.InstanceBuilder(reportInstName=reportInstName) reporter = sap_abap.InstanceReporter(builder) pdo = sap_abap.InstanceBuilder.createPdo(inst, system) else: builder = sap_abap.AscsInstanceBuilder(reportInstName=reportInstName) reporter = sap_abap.InstanceReporter(builder) pdo = sap_abap.AscsInstanceBuilder.createPdo(inst, system) instOsh = reporter.reportInstance(pdo, hostOsh) vector.add(instOsh) linkReporter = sap.LinkReporter() vector.add(linkReporter.reportMembership(systemOsh, instOsh)) return vector
def reportInst(inst, system, systemOsh, clusterOsh, ips, reportInstName=False): r'@types: sap.Instance, sap.System, osh, osh, list[str], bool -> oshv' hostReporter = sap.HostReporter(sap.HostBuilder()) hostOsh, hVector = hostReporter.reportHostWithIps(*ips) instBuilder = InstanceBuilder(reportInstName=reportInstName) instReporter = InstanceReporter(instBuilder) linkReporter = sap.LinkReporter() vector = ObjectStateHolderVector() vector.addAll(hVector) #report systemOsh systemOsh.setStringAttribute( 'data_note', 'This SAP System link to ' + hostOsh.getAttributeValue('host_key')) vector.add(systemOsh) pdo = InstanceBuilder.InstancePdo(inst, system) instOsh = instReporter.reportInstancePdo(pdo, hostOsh) vector.add(linkReporter.reportMembership(clusterOsh, instOsh)) vector.add(linkReporter.reportMembership(systemOsh, instOsh)) vector.add(instOsh) return instOsh, hostOsh, vector
def report_system(system_name, instance_number, ip_address, application_ip=None, cred_id=None): oshs = [] system = sap.System(system_name) system_osh = sap.Builder().buildSapSystem(system) instance_osh = InstanceBuilder(reportName=False, reportInstName=False).buildNoNameInstance( instance_number, None, system, applicationIp=application_ip, credId=cred_id) host_osh = modeling.createHostOSH(ip_address) instance_osh.setContainer(host_osh) oshs.append(system_osh) oshs.append(instance_osh) linkReporter = sap.LinkReporter(sap.LinkBuilder()) oshs.append(linkReporter.reportMembership(system_osh, instance_osh)) return system_osh, oshs
def reportTrexHostNode(hostNode, topology, isBiaProduct): r'@types: TrexTopologyConfig.HostNode, TrexTopologyConfig, bool -> ObjectStateHolderVector' trexBuilder = sap_trex.Builder() trexReporter = sap_trex.Reporter(trexBuilder) hostReporter = sap_trex.HostReporter(sap_trex.HostBuilder()) endpointReporter = netutils.EndpointReporter( netutils.ServiceEndpointBuilder()) linkReporter = sap.LinkReporter() softwareBuilder = sap.SoftwareBuilder() # x) create sap system system = hostNode.system vector = ObjectStateHolderVector() # process NameServer endpoints and ignore loopback endpoints isLoopbackEndpoint = lambda e: netutils.isLoopbackIp(e.getAddress()) _, endpoints = fptools.partition(isLoopbackEndpoint, hostNode.nameServerEndpoints) # x) create host OSH hostOsh = hostReporter.reportHostByHostname(hostNode.name) vector.add(hostOsh) # x) report IPs ips = map(netutils.Endpoint.getAddress, endpoints) ipOshs = map(modeling.createIpOSH, ips) fptools.each(vector.add, ipOshs) #vector.addAll(ipOshs) # x) report containment between host nad ips reportContainment = fptools.partiallyApply(linkReporter.reportContainment, hostOsh, fptools._) fptools.each(vector.add, map(reportContainment, ipOshs)) # x) report end-points reportEndpoint = fptools.partiallyApply(endpointReporter.reportEndpoint, fptools._, hostOsh) endpointOshs = map(reportEndpoint, endpoints) fptools.each(vector.add, endpointOshs) # x) report TREX instance itself instanceOsh = trexReporter.reportInstance(first(system.getInstances()), hostOsh) # x) mark as BIA or plain-TREX productName = (isBiaProduct and sap_trex.Product.BIA.instanceProductName or sap_trex.Product.TREX.instanceProductName) softwareBuilder.updateDiscoveredProductName(instanceOsh, productName) # x) set name server role (master, slave or 1st master) nameServerPort = first(endpoints).getPort() nameServerEndpoint = netutils.createTcpEndpoint(hostNode.name, nameServerPort) topologyGlobals = topology.getGlobals() isMaster = nameServerEndpoint in (fptools.safeFunc( topologyGlobals.getMasterEndpoints)() or ()) isActiveMaster = nameServerEndpoint in (fptools.safeFunc( topologyGlobals.getActiveMasterEndpoints)() or ()) trexBuilder.updateNameServerMode( instanceOsh, (isMaster and (isActiveMaster and sap_trex.NameServerMode.FIRST_MASTER or sap_trex.NameServerMode.MASTER) or sap_trex.NameServerMode.SLAVE)) vector.add(instanceOsh) # x) DO NOT report 'membership' between system and instance # Explanation: # sometimes you can discover systems that don't have relationship to current host. # This can lead to incorrect merging of to systems (inside OSH vector) # systemOsh = trexReporter.reportSystem(system) # vector.add(systemOsh) # vector.add(linkReporter.reportMembership(systemOsh, instanceOsh)) # x) report 'usage' between instance and endpoints of name-server reportUsage = fptools.partiallyApply(linkReporter.reportUsage, instanceOsh, fptools._) fptools.each(vector.add, map(reportUsage, endpointOshs)) 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 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))
process = self._process shell = context.client system = self.get_sap_system() logger.info("Discover message server hostname from profile") hostname = _discover_msg_hostname(shell, self._pf_path) if hostname: osh = self.software_builder.updateHostname(osh, hostname) logger.info("Discover message server port") try: listen_endpoints = app.getEndpointsByProcess(process) ip_endpoints = self.get_service_endpoints(shell, system, listen_endpoints, app) osh.setIntegerAttribute('application_port', int(ip_endpoints[0].getPort())) except (JException, Exception), e: logger.warn("Failed to get process endpoints. %s" % e) else: linkReporter = sap.LinkReporter() vector = context.resultsVector service_name = sap.MessageServerBuilder.SERVICE_NAME for ip_endpoint in ip_endpoints: host_osh = app.getHostOsh() ip_endpoint_builder = netutils.ServiceEndpointBuilder() reporter = netutils.EndpointReporter(ip_endpoint_builder) ip_endpoint_osh = reporter.reportEndpoint(ip_endpoint, host_osh) ip_endpoint_builder.setNameAttr(ip_endpoint_osh, service_name) vector.add(linkReporter.reportUsage(osh, ip_endpoint_osh)) vector.add(ip_endpoint_osh) def get_version_cmd(self, bin_path): return GetMsgServerVersionInfo(bin_path) def get_service_endpoints(self, shell, system, endpoints, application_server):
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)