예제 #1
0
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
예제 #2
0
def parseSapSystemFromInstanceBasePath(path, parseHostname=False):
    r''' Parse instance base path and decompose it onto system and instance
    object representation.
    Format of substring participated in search is
    /<SAPSYSTEMNAME>/<INSTANCE_NAME>/<SAPLOCALHOST>

    @types: str, bool -> sap.System
    @param parseHostname: Influence on <SAPLOCALHOST> part parsing.
        When parameter set to True will attempt to parse hostname.
        Parameter has to be used carefully and only in places where there is
        confidence in right pattern format.
    @raise ValueError: Unsupported path format'''
    if not path:
        raise ValueError("Path is not specified")
    mo = re.search(
        r'''[/\\]([a-z]{3})[/\\]       # SAPSYSTEMNAME
                       ([a-z]+)(\d\d)             # INSTANCE_NAME
                       (?:[/\\]([^/\\]+))?\s*     # SAPLOCALHOST
                    ''', path, re.I | re.VERBOSE)
    if not mo:
        raise ValueError("Unsupported path format")
    sid = mo.group(1)
    number = mo.group(3)
    name = mo.group(2) + number
    hostname = None
    if parseHostname and len(mo.groups()) > 3:
        hostname = mo.group(4).strip()
    return sap.System(sid).addInstance(sap.Instance(name, number, hostname))
예제 #3
0
def parseInstanceFromName(instanceName):
    r'@types: str -> sap.Instance'
    assert instanceName
    matchObj = re.match(r'\s*([a-z]+?)(\d+)', instanceName, re.I)
    if matchObj:
        return sap.Instance(matchObj.group(1), matchObj.group(2))
    raise ValueError("Wrong instance name")
예제 #4
0
def parse_inst_in_pf(doc):
    '''
    Parse instance related information from profile
    @types: IniDocument -> sap.Instance
    '''
    inst = parseInstanceFromName(doc.get('INSTANCE_NAME'))
    hostname = doc.get('SAPLOCALHOST')
    fqdn = doc.get('SAPLOCALHOSTFULL')
    if not hostname and fqdn and not _has_substitution_variable(fqdn):
        hostname = parse_hostname_from_fqdn(fqdn)
    return sap.Instance(inst.name, inst.number, hostname)
예제 #5
0
 def _parseInstFullInformation(self, props):
     r'@types: java.util.Properties -> sap.Instance'
     name = props.get('InstanceName')
     vmParameters = props.get('VmParameters') or ()
     inst = self._parseInst(name, vmParameters)
     if not inst:
         raise ValueError("Failed to parse instance information")
     myName = _findJavaSysParameter(vmParameters, 'SAPMYNAME')
     hostname = None
     if myName:
         _, hostname, _ = sap_discoverer.parseSystemAndInstanceDetails(myName)
     return sap.Instance(inst.getName(), inst.getNumber(), hostname)
예제 #6
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)))
예제 #7
0
    def _extractInstanceInfoFromProfilePath(self, sid, path):
        r''' Profile file name contains information about instance name and
        its number in format '<something>_<instance-name>_<something>'

        @types: str -> sap.Instance'''
        if not (path and sid):
            raise ValueError("Path or SID is not specified")
        matchObj = re.match(r'.*?(?:START|%s)_(.+?)(\d+)_(\w+)' % sid, path,
                            re.I)
        if matchObj:
            return sap.Instance(matchObj.group(1),
                                matchObj.group(2),
                                hostname=matchObj.group(3))
        raise ValueError("Failed to parse instance from profile name")
예제 #8
0
 def _parseScsInstance(self, document):
     r'''@types: IniDocument -> tuple[sap.Instance, Endpoint or None]
     @return: tuple of SCS instance itself and message server endpoint
     '''
     instance = None
     msEndpoint = None
     hostname = document.get('j2ee/scs/host')
     number = document.get('j2ee/scs/system')
     msPort = document.get('j2ee/ms/port')
     if hostname and number:
         instance = sap.Instance('SCS', number, hostname)
         if msPort:
             msEndpoint = netutils.createTcpEndpoint(hostname, msPort)
     return instance, msEndpoint
예제 #9
0
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
예제 #10
0
 def _parseInstanceInfo(self, item):
     r'@types: Properties -> InstanceInfo'
     hostname = item.get('Host')
     if not hostname:
         raise ValueError("Address is not specified")
     ports = keep(item.get, self.ENDPOINT_NAMES)
     endpoints = [netutils.createTcpEndpoint(hostname, p) for p in ports]
     state = self._parseInstanceState(item.get('State'))
     instName = item.get('Caption')
     fullName = item.get('Name')
     _inst = sap_discoverer.parseInstanceFromName(instName)
     instName = _inst.name
     if fullName:
         details = sap_discoverer.parseSystemAndInstanceDetails(fullName)
         _, hostname, nr = details
     else:
         nr = _inst.number
     instanceWithHostname = sap.Instance(instName, nr, hostname=hostname)
     return self.InstanceInfo(instanceWithHostname, endpoints, state=state)
예제 #11
0
def parseSapSystemFromInstanceProfileName(profileName):
    r''' Format of profile name is: <SAPSYSTEMNAME>_<INSTANCE_NAME>_<SAPLOCALHOST>
    @types: str -> sap.System
    @raise ValueError: Wrong instance profile name

    @note: potentially relevant only to ABAP instance PF naming
    '''
    if not profileName:
        raise ValueError("Profile name is not specified")
    tokens = profileName.split('_', 2)
    if len(tokens) != 3:
        raise ValueError("Wrong instance profile name")
    systemName = tokens[0]
    instanceName = tokens[1]
    hostname = tokens[2]
    sapSystem = sap.System(systemName)
    instance = parseInstanceFromName(instanceName)
    sapSystem.addInstance(
        sap.Instance(instance.getName(), instance.getNumber(), hostname))
    return sapSystem
예제 #12
0
def _reportServer(server, parsedName, ips, system, systemOsh):
    '''
    @types: GetServers.Server, tuple, list[ip_addr._BaseIP], System, osh -> oshv
    '''
    vector = ObjectStateHolderVector()
    isScs, hostname, _, nr, _ = parsedName
    hostReporter = sap.HostReporter(sap.HostBuilder())
    hostOsh, hVector = hostReporter.reportHostWithIps(*ips)
    # 1) name of instance will be ignore during reporting
    # 2) hostname used from name not from `hostname` field of server
    #     as usually name contains alias that is interesting in different
    #     business cases
    inst = sap.Instance('fake', nr, hostname)
    serverType = GetServers.getServerTypeByRole(server.role)
    reportFn = (serverType == sap.SystemType.JAVA
                and _reportJavaServer
                or  _reportAbapServer)
    vector.addAll(hVector)
    vector.addAll(reportFn(inst, system, isScs, hostOsh, systemOsh))
    return vector
예제 #13
0
    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))
예제 #14
0
        return None


# TODO replace this by reportInstances function
def _report_ascs_osh(host_name, instance_number, system):
    resolver = dns_resolver.SocketDnsResolver()
    ips = []
    try:
        ips = resolver.resolve_ips(host_name)
    except netutils.ResolveException, re:
        logger.warn("Failed to resolve %s" % host_name)
    if ips:
        hostReporter = sap.HostReporter(sap.HostBuilder())
        host_osh, vector = hostReporter.reportHostWithIps(*ips)

        instance = sap.Instance('ASCS', instance_number, host_name)
        ascs_pdo = sap_abap.AscsInstanceBuilder.createPdo(instance, system)

        ascs_builder = sap_abap.AscsInstanceBuilder()
        reporter = sap_abap.InstanceReporter(ascs_builder)
        ascs_osh = reporter.reportInstance(ascs_pdo, host_osh)

        vector.add(ascs_osh)
        vector.add(host_osh)
        return ascs_osh, vector
    return None, None


def _updateSystemOsh(system, systemOsh):
    '@types: System, osh -> osh'
예제 #15
0
def _createAnonymousInstFromFullName(name):
    r'@types: str -> sap.Instance'
    _, hostname, nr = sap_discoverer.parseSystemAndInstanceDetails(name)
    return sap.Instance('x', nr, hostname)