Exemplo n.º 1
0
    def parse(self, content):
        r''' Parse version information per process that is identified by its PID

        File content is just a trace file which contains information per process.
        @types: str -> list[ConfigInTrace]
        '''
        assert content
        initParser = sap_discoverer.IniParser()
        tranches = []

        # x) split content onto chunks per process
        # separator is "trc file:"
        for chunk in str(content).strip().split('trc file:'):
            parts = chunk.split('F  ignore unrecognized options', 1)
            # only first part is interesting (version and arguments information)
            usefulSection = parts and parts[0] or chunk
            sections = usefulSection.split('arguments :', 1)
            if sections:
                # agent version information
                VERSION_PART = 0
                result = initParser.parseValueByNameMapping(
                    sections[VERSION_PART],
                    keyTransformationFn=string.lower,
                    valueTransformationFn=string.strip,
                    nameValueSeparator=' ')
                if result:
                    pid = result.get('pid')
                    versionInfo = sap.VersionInfo(result.get('relno'),
                                                  result.get('patchno'),
                                                  result.get('patchlevel'),
                                                  result.get('make'))
                    # arguments section
                    jstartVersionInfo = None
                    ARGUMENTS_PART = 1
                    if len(sections) > 1:
                        regexp = r'''.*?arg\[\s*5\s*\]\s*= # 5th arguemnt
                        \s*\-DSAPJStartVersion\s*=         # java system protoperty
                        \s*(\d+)\s*,                       # release information (group 1)
                        \s*patch\s*(\d+)\s*,               # patch information (2)
                        (.*)                               # version description (3)
                        '''
                        matchObj = re.search(regexp, sections[ARGUMENTS_PART],
                                             re.X | re.I)
                        jstartVersionInfo = matchObj and sap.VersionInfo(
                            matchObj.group(1),
                            matchObj.group(2),
                            description=matchObj.group(3).strip())
                    tranches.append(
                        self.ConfigInTrace(pid, versionInfo,
                                           jstartVersionInfo))
        return tranches
Exemplo n.º 2
0
 def _parseVersionInfoFromIniResult(self, result):
     r'@types: sap_discoverer.IniDoc -> sap_trex.VersionInfo'
     if not result: raise ValueError("Input is empty")
     version = result.get('saptrex version')
     matchObj = re.match('(\d+?\.\d+?)\.',
                         version)  # value has format like 7.20.09.297333
     release = matchObj and matchObj.group(1) or version
     return sap.VersionInfo(release, description=version)
Exemplo n.º 3
0
 def parseResultItem(result):
     r'''
     @types: ResultSet -> tuple[str, sap.SoftwareComponent]
     @return: pair of system name and software component
     '''
     name = result.getString("COMPONENT")
     sysName = GetComponents._parseSystemName(result)
     release = result.getString("SAPRELEASE")
     patchLevel = result.getString("EXTRELEASE")
     type_ = GetComponents._parseType(result)
     versionInfo = sap.VersionInfo(release, patchLevel=patchLevel)
     return (sysName, sap.SoftwareComponent(name, type_, None, versionInfo))
Exemplo n.º 4
0
    def __parse(self, items):
        r'@types: ? -> list[InstanceInfo]'
        servers = []
        for i in xrange(items.getRowCount()):
            name = items.getCell(i, 0)
            logger.debug('server name: %s' % items.getCell(i, 0))
            logger.debug('server hostname: %s' % items.getCell(i, 1))
            logger.debug('server ip: %s' % items.getCell(i, 4))
            try:
                logger.debug("Process server: %s" % name)
                hostname, sid, number = self._decomposeServerName(name)
                # get instance name from start profile path
                startPfPath = items.getCell(i, 9)
                instancePfPath = items.getCell(i, 10)
                instance = self._extractInstanceInfoFromProfilePath(
                    sid, startPfPath or instancePfPath)
                instance = sap.Instance(instance.name,
                                        number,
                                        hostname,
                                        startPfPath=startPfPath,
                                        instancePfPath=instancePfPath)

                sapSystem = sap.System(sid)

                # host-info
                ip = sap.createIp(items.getCell(i, 4))
                hostname = items.getCell(i, 1) or hostname
                address = sap.Address(hostname, (ip, ))
                host = self.Host(address,
                                 osInfo=items.getCell(i, 2),
                                 machineType=items.getCell(i, 3))

                # server-info
                startDate = self._parseStartDate(items.getCell(i, 5))

                versionInfo = sap.VersionInfo(items.getCell(i, 6),
                                              patchLevel=items.getCell(i, 8))

                instanceInfo = self.createInstanceInfo(
                    instance,
                    sapSystem,
                    host,
                    homeDirPath=items.getCell(i, 11),
                    dbLibraryInfo=items.getCell(i, 7),
                    codePage=items.getCell(i, 12),
                    numberOfProcesses=items.getCell(i, 13),
                    versionInfo=versionInfo,
                    startDate=startDate)
                servers.append(instanceInfo)
            except Exception, e:
                logger.warnException("%s. %s" % (name, str(e)))
Exemplo n.º 5
0
 def getVersionInfo(self, filePath):
     '@types: str -> sap.VersionInfo'
     output = self.shell.execCmd('"%s" -v' % filePath)
     if output and output.strip():
         versionData = re.match(
             '.*CCMS version\s+(.*?)'
             'compiled.*relno\s+(\d)(\d+).*'
             'patch text\s+(.*?)\n.*'
             'patchno\s+(\d+)', output, re.DOTALL)
         release = "%s.%s" % (versionData.group(2), versionData.group(3))
         patchNumber = versionData.group(5)
         description = '%s, %s, %s, patch number %s' % (
             release, versionData.group(1).strip(),
             versionData.group(4).strip(), patchNumber)
         return sap.VersionInfo(release,
                                patchNumber,
                                description=description)
Exemplo n.º 6
0
 def parseVersionInfo(self, result):
     r'''@types: command.Result -> sap.VersionInfo'''
     output = result.output
     valueByName = sap_discoverer.IniParser().parseValueByNameMapping(
         # output prefixed with description to get first line
         "description=%s" % output.strip(), valueTransformationFn=string.strip)
     kernelPatchLevel = None
     sourceId = valueByName.get('source id')
     level_match = re.match(re.compile(r'\d+\.(\d+)'), sourceId)
     if level_match:
         kernelPatchLevel = level_match.group(1)
     return sap.VersionInfo(
         valueByName.get('kernel release'),
         valueByName.get('patch number'),
         valueByName.get('update level'),
         valueByName.get('compiled on'),
         kernelPatchLevel
     )
Exemplo n.º 7
0
 def parse(self, output):
     '@types: str -> sap.VersionInfo?'
     file_content_lines = output.splitlines()
     kernel_release = None
     patch_number = None
     patch_level = None
     for line in file_content_lines:
         level_match = (self.PATCH_LEVEL_REGEX
                        and re.match(self.PATCH_LEVEL_REGEX, line))
         match = re.match(self.RELEASE_VERSION_REGEX, line)
         if match:
             kernel_release = match.group(1)
         elif level_match:
             patch_level = level_match.group(1)
         else:
             found_patch_number = re.match(self.PATCH_NUMBER_REGEX, line)
             if found_patch_number:
                 patch_number = found_patch_number.group(1)
     if kernel_release:
         return sap.VersionInfo(kernel_release,
                                patchNumber=patch_number,
                                patchLevel=patch_level)
Exemplo n.º 8
0
 def getComponents(self):
     r''' Get list of software components available in the system
     @types: -> list[sap.SoftwareComponent]
     '''
     resultSet = self.getJcoClient().executeQuery(
         "CVERS", None, "COMPONENT,RELEASE,EXTRELEASE,COMP_TYPE"
     )  # @@CMD_PERMISION sap protocol execution
     components = []
     while resultSet.next():
         componentType = resultSet.getString("COMP_TYPE")
         try:
             release = resultSet.getString("RELEASE")
             components.append(
                 sap.SoftwareComponent(
                     resultSet.getString("COMPONENT"),
                     componentType,
                     versionInfo=(release and sap.VersionInfo(
                         release,
                         patchLevel=resultSet.getString("EXTRELEASE"))
                                  or None)))
         except sap.SoftwareComponent.TypeIsNotRecognized, ex:
             logger.warn("%s: %s" % (str(ex), componentType))
         except:
Exemplo n.º 9
0
    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)