Example #1
0
    def btc_xmi_logoff(self):
        """ Perform BAPI XMI Log Off

        OSS Notes:
            1770388 - Enhancements in the XBP interface

        :return:Fail(error Message
        """
        self.logger.debug('starting BAPI_XMI_LOGOFF')
        result = self.call_fm('BAPI_XMI_LOGOFF', INTERFACE='XBP')

        if result.fail:
            return result

        result=result.data
        if result['RETURN']['TYPE'] == 'E':
            if result['RETURN']['NUMBER'] != '028':
                logMessage = 'BAPI_XMI_LOGOFF: {:s}'.format(result['RETURN']['MESSAGE'])
                self.logger.error(logMessage)
                return Fail(message=logMessage)
            else:
                self.logger.debug('user was not logged on to interface')
                return Result(data=True)
        else:
            self.logger.debug('BAPI_XMI_LOGOFF successful')
            return Result(data=True)
    def execute(self):

        checkobj = self.checkObject
        for id, parameterSet in enumerate(checkobj.params):
            self.logger.debug('Parameter Set {}, Options: {}'.format(
                id, pformat(parameterSet.__repr__)))
            record = dict(RATING='pass',
                          WHERE_CLAUSE=parameterSet.where_clause,
                          TABLE=parameterSet.table_name,
                          EXPECTED=parameterSet.expected_count,
                          OPERATOR=self.operators.lookup(
                              parameterSet.operator),
                          PARAMETERSET=parameterSet.param_set_name)

            tab_fields = parameterSet.table_fields.split(';')

            result = self.retrieveData(tabname=record['TABLE'],
                                       where_clause=record['WHERE_CLAUSE'],
                                       tab_fields=tab_fields)
            if not result.fail:
                downloaded_data = result.data['data']
                record['CONFIGURED'] = len(downloaded_data)
            else:
                record['CONFIGURED'] = result.fail
                record['RATING'] = 'error'
                self.actionResult.add_result(record)
                self.actionResult.rating = 'error'
                return Result(self.actionResult)

            record = self.rateIndividualResult(record)
            self.actionResult.addResult(record)

        self.rateOverallResult()

        return Result(data=self.actionResult)
    def _profileContents(self):
        """ Get Contents of all profiles

        :param profilename: Profile Name

        Parameter values spanning over multiple lines, are identified by column COMNR.


        """

        result=self._profileNames()
        if result.fail:
            return result

        profilenames=result.data

        self.logger.debug('Reading Profile Contents')
        self.logger.debug('Reading Default Profile from DB')

        profileContents=dict(DEFAULT=[],
                             INSTANCE=[],
                             START=[])

        for type, names in profilenames.items():
            for name in names:
                result=self._singleProfileContent(name)
                if result.fail:
                    return result

                profileContents[type].extend(result.data)

        return Result(data=profileContents)
Example #4
0
    def btc_xbp_job_definition_get(self, jobname:str, jobcount:str):
        """ Retrive the definition of a specfic job using function module BAPI_XBP_JOB_DEFINITION_GET.

        :param jobname: Name of the job
        :param jobcount: Job Nubmber
        :param extUserName: External User name
        :return:
        """

        self.logger.debug('starting BAPI_XBP_JOB_DEFINITION_GET')

        fmParameters = dict(JOBNAME=jobname,
                            JOBCOUNT=jobcount,
                            EXTERNAL_USER_NAME=self.XBP_EXT_USER)

        result = self.call_fm('BAPI_XBP_JOB_DEFINITION_GET', **fmParameters)

        if result.fail:
            return result

        result=result.data
        if result['RETURN']['TYPE'] == 'E':
            logMessage = 'BAPI_XBP_JOB_DEFINITION_GET for job {} ({}) failed: {}'.format(jobname, str(jobcount), result['RETURN']['MESSAGE'])
            self.logger.error(logMessage)
            return Fail(message=logMessage)
        else:
            self.logger.debug('BAPI_XBP_JOB_DEFINITION_GET successful: ' + pformat(result))
            return Result(data=result)
Example #5
0
    def logon(self, logon_info:dict, mock:bool=False, mockdata:dict=False)->Union[Result, Fail]:
        """ Logon to the specified system

        :param logon_info: Information required to logon to a system
        :param mock: If True, then no real pyRFC conection will be established. This is for testing.
        :param moockdata: Data that should be used for the mock testing

        """

        if logon_info is False:
            return Fail(message='Logon Info Incomplete')

        self.mock = mock
        self.logger = logging.getLogger('{}.{}'.format(__name__, self.__class__.__name__))
        result = Result(message='Connection Successful')
        if mock:
            try:
                self.conn = MockConnection(mockdata=mockdata)
            except Exception as err:
                return Fail('Mock Connection Setup Failed')
        else:
            try:
                self.logger.debug('Logon Details: %s', pformat(logon_info))
                self.conn = pyrfc.Connection(**logon_info)
            except Exception as err:
                result = self._handle_exception(err)
        return result
Example #6
0
    def btc_xbp_job_close(self, jobname, jobcount):
        """ Closes the job definition

        OSS Notes:
            1770388 - Enhancements in the XBP interface

        :param jobname: Job Name
        :param jobcount: Unique job count number for the background job
        :return: Result(True) if successful Fail(Error Message)
        """

        self.logger.debug('starting BAPI_XBP_JOB_CLOSE')
        result = self.call_fm('BAPI_XBP_JOB_CLOSE', JOBNAME=jobname,
                           JOBCOUNT=jobcount,
                           EXTERNAL_USER_NAME=self.XBP_EXT_USER)

        if result.fail:
            return result

        result=result.data

        if result['RETURN']['TYPE'] == 'E':
            logMessage = 'BAPI_XBP_JOB_CLOSE for {:s} ({:s}: '.format(jobname, jobcount,
                                                                      result['RETURN']['MESSAGE'])
            self.logger.error(logMessage)
            return Fail(message=logMessage)
        else:
            self.logger.debug('schedule_job_immediately: BAPI_XBP_JOB_CLOSE successful')
            return Result(data=True)
Example #7
0
    def btc_xmi_logon(self, interface:str='XBP'):
        """Starting BAPI XMI logon process

        OSS Notes:
            1770388 - Enhancements in the XBP interface

        :param externalCompany: Name of the external company
        :param externalProduct: Name of the external product
        :param interface: Interface to logon to
        :param version: Version of the interface
        :return: Fail(error Message) or Result(True)
        """

        self.logger.debug('starting BAPI_XMI_LOGON')
        result = self.call_fm('BAPI_XMI_LOGON', EXTCOMPANY=self.XBP_EXT_COMPANY,
                           EXTPRODUCT=self.XBP_EXT_PRODUCT,
                           INTERFACE=interface,
                           VERSION=self.XPB_INTERFACE_VERS)

        if result.fail:
            return result

        result=result.data

        if result['RETURN']['TYPE'] == 'E' and result['RETURN']['MESSAGE'] != 'Tool already logged on in interface XBP':
            logMessage = 'BAPI_XMI_LOGON: {:s}'.format(result['RETURN']['MESSAGE'])
            sid = self.sid()
            client = self.conn.get_connection_attributes().get('client')

            self.logger.error('%s Client %s: %s', sid, client, logMessage)
            return Fail(message=logMessage)
        else:
            self.logger.debug('BAPI_XMI_LOGON successful')
            result=Result(data=True)
            return result
Example #8
0
    def btc_xbp_job_start_immediately(self, jobname, jobcount):
        """ Starts a defined job immediately

        OSS Notes:
            1770388 - Enhancements in the XBP interface

        :param jobname: Name of the Job
        :param jobcount: Unique job count number for the background job
        :return:
        """

        self.logger.debug('starting BAPI_XBP_JOB_START_IMMEDIATELY')
        result = self.call_fm('BAPI_XBP_JOB_START_IMMEDIATELY', JOBNAME=jobname,
                           JOBCOUNT=jobcount,
                           EXTERNAL_USER_NAME=self.XBP_EXT_USER)

        if result.fail:
            return result

        result=result.data
        if result['RETURN']['TYPE'] == 'E':
            logMessage = 'BAPI_XBP_JOB_START_IMMEDIATELY for {:s} ({:s}): {:s}'.format(jobname, jobcount,
                                                                                       result['RETURN']['MESSAGE'])
            self.logger.error(logMessage)
            return Fail(message=logMessage)
        else:
            self.logger.debug('schedule_job_immediately: BAPI_XBP_JOB_START_IMMEDIATELY successful')
            return Result(data=True)
Example #9
0
    def instances(self) -> Union[Result, Fail]:
        """ Returns the names of the instances as list"""
        fm_result = self.call_fm('TH_SERVER_LIST')
        if fm_result.fail:
            return fm_result

        result = [instance['NAME'] for instance in fm_result.data['LIST']]

        return Result(data=result)
Example #10
0
    def call_fm(self, fm: str, **kwargs) -> Union[Result, Fail]:
        """ Call Function Module with Exception Handling"""
        self.logger.debug('Executing Function Module {}'.format(fm))

        try:
            data = self.conn.call(fm, **kwargs)
        except Exception as err:
            return(self._handle_exception(err))
        return Result(message='call to {} successful'.format(fm), data=data)
Example #11
0
    def component(self, component:str)-> Result:
        """ Check whether a component is installed and retrieve the versions


        :param component: the name of the component
        """

        where_clause="COMPONENT EQ '{}'".format(component.upper())

        result=self.download_table('CVERS', where_clause=where_clause, tab_fields=['COMPONENT'])
        if result.fail:
            return result

        data=result.data.get('data')
        if len(data):
            return Result(data=data[0])
        else:
            return Result(data=[])
Example #12
0
def get_connection(logon_info:dict)->Union[Result, Fail]:
    """ Establish a connection to an ABAP System


    """

    connection = Connection()
    result = connection.logon(logon_info)
    if not result.fail:
        result=Result(message='Logon Successful', data=connection)
    return result
Example #13
0
    def btc_xbp_job_log_read(self, jobname, jobcount, protNew=None, lines=None, direction=None):
        """ Read the log of the specified job.

        :param protNew:
        :param lines:
        :param direction:
        :param jobname: Name of the job
        :param jobcount: Job Nubmber
        :param extUserName: External User name
        :return:
        """

        self.logger.debug('starting BAPI_XBP_JOB_JOBLOG_READ')

        fmParameters = dict(JOBNAME=jobname,
                            JOBCOUNT=jobcount,
                            EXTERNAL_USER_NAME=self.XBP_EXT_USER)

        if protNew:
            fmParameters['PROT_NEW'] = protNew

        if lines:
            fmParameters['LINES'] = lines

        if direction:
            fmParameters['DIRECTION'] = direction

        result = self.call_fm('BAPI_XBP_JOB_JOBLOG_READ', **fmParameters)

        if result.fail:
            return result

        result=result.data
        if result['RETURN']['TYPE'] == 'E':
            logMessage = 'BAPI_XBP_JOB_JOBLOG_READ for job {:s} ({:d}) failed: {:s}'.format(jobname,
                                                                                            int(jobcount),
                                                                                            result['RETURN'][
                                                                                                'MESSAGE'])
            self.logger.error(logMessage)
            return Fail(logMessage)
        else:
            self.logger.debug('BAPI_XBP_JOB_JOBLOG_READ successful: ' + pformat(result))
            return Result(result)
    def _profileNames(self)->Result:
        """ Get the names of the Profiles in the database """
        self.logger.debug('reading profiles from system')
        instance_profiles = None
        start_profiles = None
        result = self.systemConnection.call_fm('PFL_GET_PROF_LIST')
        if result.fail:
            return result

        instance_profiles = set(
            [record['PFNAME'] for record in result.data['HEADER_TAB'] if record['TYPE'] == 'I'])
        start_profiles = set(
            [record['PFNAME'] for record in result.data['HEADER_TAB'] if record['TYPE'] == 'S'])
        default_profiles = set(
            [record['PFNAME'] for record in result.data['HEADER_TAB'] if record['TYPE'] == 'D'])

        result=Result(data={'DEFAULT':default_profiles, 'INSTANCE':instance_profiles, 'START':start_profiles})

        return result
Example #15
0
    def get_runtime_parameter(self, parameter):

        """ Get the value of the specified profile parameter
        :param configParameter: profile parameter to query
        :return: Result({value:... , name:parameter}) or Fail(message)
        """

        result = self.call_fm('SXPG_PROFILE_PARAMETER_GET', PARAMETER_NAME=parameter)

        if result.fail:
            return result

        response=result.data

        if response['RET']!=0:
            return Fail('Error Retrieving Value of {}'.format(parameter))


        return Result(data={'value': response['PARAMETER_VALUE'], 'name': parameter})
Example #16
0
    def systemtime(self):
        """ Get System Timezone

        The function calls function module TH_GET_START_TIME2. A sample execution is documented below. START_TIME is
        the number of seconds since 01.01.1970 (epoch). Uptime is specified in seconds.

        TS_GMTIME is the start time in UTC, TS_LOCALTIME is the start time in the local time zone of the server.


        --------------------------------------------------------------------------------
        | Export parameters              |Value                                        |
        --------------------------------------------------------------------------------
        | START_TIME                     |1484444152                                   |
        | START_TIME_STR                 |Sun Jan 15 01:35:52 2017                     |
        | UPTIME                         |1,157                                        |
        | TS_GMTIME                      |20170115013552                               |
        | TS_LOCALTIME                   |20170115013552                               |
        --------------------------------------------------------------------------------



        """
        self.logger.debug('retrieving system time')
        result=self.call_fm('TH_GET_START_TIME2')
        if result.fail:
            self.logger.debug('Failed to retrieve system time: %s', result.message)
            return result
        uptime=int(result.data['UPTIME'])
        starttime=int(result.data['START_TIME'])
        localstarttime=datetime.datetime.strptime(result.data['TS_LOCALTIME'],'%Y%m%d%H%M%S')
        localtime=localstarttime + datetime.timedelta(seconds=uptime)
        utcstarttime=datetime.datetime.strptime(result.data['TS_GMTIME'],'%Y%m%d%H%M%S')
        utctime=localstarttime + datetime.timedelta(seconds=uptime)

        result=dict(uptime = uptime,
                    starttime = starttime,
                    localtime = localtime,
                    localstarttime = localstarttime,
                    utctime=utctime,
                    utcstarttime=utcstarttime)
        self.logger.debug('System Times: %s', pformat(result))
        return Result(data=result)
Example #17
0
def importChecks(path=None, session=None):
    """ Import all Checks


    :param path: The path to the checks """
    logger.debug('Import Checks')

    success = dict()  #will be used for status tracking
    failed = dict()  #will be used for status tracking

    if path is None:
        logger.debug('No path specified, using default path')
        path = get_absolute_systemcheck_path('checks/dump')

    logger.debug('Path: %s', path)

    checkFiles = [
        f for f in listdir(path)
        if isfile(join(path, f)) and f.endswith('.yaml')
    ]

    logger.debug('idenfied files: %s', pformat(checkFiles))
    logger.debug('starting import:')
    for checkFile in checkFiles:
        logger.debug('  - %s', checkFile)

        result = importCheck(filename=join(path, checkFile), session=session)
        if result.fail:
            logger.error('Import of %s failed: %s', checkFile, result.message)
            failed[checkFile] = result.message
        else:
            logger.debug('Import of %s succeeded', checkFile)
            success[checkFile] = result.message

        if len(failed) > 0:
            message = 'Some imports failed!'
        else:
            message = 'Imports Succeeded'

        data = {'successful': success, 'failed': failed}

    return Result(message=message, data=data)
Example #18
0
    def btc_xbp_get_spool_as_dat(self, spoolRequest, firstPage=None, lastPage=None):
        """ Download spool request as .csv file

        This procedure requires function module BAPI_XBP_GET_SPOOL_AS_DAT which is delivered in the
        OSS note below:

            1515293 - Transferring spool requests as delimited tab text files

        :param spoolRequest: Spool Request Number
        :param firstPage: First page of the spool request to download
        :param lastPage: Last page of the spool request to download.
        :return: Result(data) if successful or Fail(Message) if error
        """


        self.logger.debug('starting BAPI_XBP_GET_SPOOL_AS_DAT')

        fmParameters = dict(SPOOL_REQUEST=int(spoolRequest),
                            EXTERNAL_USER_NAME=self.XBP_EXT_USER)

        if firstPage:
            fmParameters['FIRST_PAGE'] = firstPage

        if lastPage:
            fmParameters['LAST_PAGE'] = lastPage

        result = self.call_fm('BAPI_XBP_GET_SPOOL_AS_DAT', **fmParameters)

        if result.fail:
            return result

        result = result.data
        if result['RETURN']['TYPE'] == 'E':
            logMessage = 'BAPI_XBP_GET_SPOOL_AS_DAT for spool request {:s}: {:s}'.format(spoolRequest,
                                                                                         result['RETURN'][
                                                                                             'MESSAGE'])
            self.logger.error(logMessage)
            return Fail(logMessage)

        self.logger.debug('BAPI_XBP_GET_SPOOL_AS_DAT successful')
        return Result(data=result)
    def execute(self):

        checkobj = self.checkObject

        result = self.systemConnection.call_fm('TH_SERVER_LIST')
        if not result.fail:
            instances=result.data
        else:
            self.rateOverallResult(error=True, errormessage=result.fail)
            return Result(data=self.actionResult)

        for parameterSet in checkobj.params:

            for instance in instances['LIST_IPV6']:
                record = dict(RATING='pass',
                              PARAMETERSET=parameterSet.param_set_name,
                              PARAMETER=parameterSet.parameter,
                              EXPECTED=parameterSet.expected_value,
                              INSTANCE=instance['NAME'],
                              OPERATOR=self.operators.lookup(parameterSet.operator))
                logonInfo=self._adaptLogonInfo(instance)
                result=ABAP.utils.get_connection(logonInfo)
                if result.fail:
                    record['RATING']='error'
                    record['CONFIGURED']=result.fail
                    self.actionResult.addResult(record)
                else:
                    connection=result.data
                    result=connection.get_runtime_parameter(record['PARAMETER'])
                    if result.fail:
                        record['RATING'] = 'error'
                        record['CONFIGURED']=result.fail
                        self.actionResult.addResult(record)
                    else:
                        response=result.data
                        record['CONFIGURED']=response['value']
                        record = self.rateIndividualResult(record)
                        self.actionResult.addResult(record)
                    connection.close()
        self.rateOverallResult()
    def _singleProfileContent(self, profilename:str):
        """ Get the content of a single profile


        :param profilename: NAme of the profile to download """

        result = self.systemConnection.call_fm('PFL_READ_PROFILE_FROM_DB', PROFILE_NAME=profilename)

        if result.fail:
            return result

        profileData = result.data.get('DTAB')
        parameter = None
        value = None

        configuredParameters = list()

        # Append an empty row at the end of the data
        profileData.append({'PARNAME': None, 'COMNR': '0001'})

        for counter, row in enumerate(profileData):
            if row['PARNAME'] and row['COMNR'] == '9990':
                if parameter and value and profilename:
                    configuredParameters.append(dict(PVALUE=value, PARNAME=parameter, PFNAME=profilename))
                parameter = row['PARNAME']
                value = row['PVALUE']
                profilename=row['PFNAME']
            elif row['COMNR'] in ['9991', '9992', '9993', '9994', '9995', '9996', '9997', '9998', '9999']:
                value += row['PVALUE']
            elif row['COMNR'] == '0001':
                if parameter and value:
                    record=dict(PVALUE = value,
                                PARNAME = parameter,
                                PFNAME = profilename)
                    configuredParameters.append(record)
                    parameter = None
                    value = None
                    profilename = None

        return Result(data=configuredParameters)
Example #21
0
    def btc_xbp_add_ext_job_step(self, jobname, jobcount, extProgramName, extProgramParameters, sapUserName,
                           destinationHost=None):
        """ Add external program as Step to the Job

        OSS Notes:
            1770388 - Enhancements in the XBP interface

        :param extProgramName: Name of the external program
        :param extProgramParameters: Parameters for the external program
        :param sapUserName: SAP Username
        :param jobname: Name of the background job
        :param jobcount: Unique job count number for the background job
        :param program: ABAP Program Name
        :return: Result(True) if the message succeeds Fail(Message) if step fails.
        """
        fmOptions = dict(JOBNAME=jobname,
                         JOBCOUNT=jobcount,
                         EXTERNAL_USER_NAME=self.XBP_EXT_USER,
                         EXT_PROGRAM_NAME=extProgramName,
                         EXT_PROGRAM_PARAMETERS=extProgramParameters,
                         SAP_USER_NAME=sapUserName)

        if destinationHost:
            fmOptions['TARGET_HOST'] = destinationHost

        self.logger.debug('calling function module BAPI_XBP_JOB_ADD_EXT_STEP with parameters %s', pformat(fmOptions))

        result = self.call_fm('BAPI_XBP_JOB_ADD_EXT_STEP', **fmOptions)

        if result.fail:
            return result

        result=result.data

        if result['RETURN']['TYPE'] == 'E':
            self.logger.error('BAPI_XBP_JOB_ADD_EXT_STEP:' + result['RETURN']['MESSAGE'])
            return Fail('BAPI_XBP_JOB_ADD_EXT_STEP:' + result['RETURN']['MESSAGE'])
        else:
            self.logger.debug('BAPI_XBP_JOB_ADD_EXT_STEP successful')
            return Result(data=True)
    def execute(self):

        result = self._profileContents()
        if result.fail:
            self.rateOverallResult(error=True, errormessage=result.fail)
            return Result(data=self.actionResult)

        profileContents=result.data
        profileReference=ProfileParameterReference(profileContents)

        for parameterSet in self.checkObject.params:

            profiledata = profileReference.getValue(parameterSet.parameter, parameterSet.profiletype)

            if len(profiledata) == 0:
                record = dict(PARAMETERSET=parameterSet.param_set_name,
                              PARAMETER=parameterSet.parameter,
                              RATING='pass',
                              PROFILETYPE=parameterSet.profiletype,
                              OPERATOR=self.operators.lookup(parameterSet.operator),
                              EXPECTED=parameterSet.expected,
                              PROFILENAME='',
                              CONFIGURED=None)
                record=self.rateIndividualResult(record)
                self.actionResult.addResult(record)
            else:
                for data in profiledata:
                    record = dict(PARAMETERSET=parameterSet.param_set_name,
                                  PARAMETER=parameterSet.parameter,
                                  RATING='pass',
                                  PROFILETYPE=parameterSet.profiletype,
                                  OPERATOR=self.operators.lookup(parameterSet.operator),
                                  PROFILENAME=data.get('PFNAME'),
                                  EXPECTED=parameterSet.expected,
                                  CONFIGURED=data.get('PVALUE'))

                    record = self.rateIndividualResult(record)
                    self.actionResult.addResult(record)
Example #23
0
    def btc_xbp_variant_delete(self, abapProgramName:str, abapVariantName:str):
        """ Delete variant for ABAP program

        :param abapProgramName: Program name
        :param abapVariantName: variant name
        :return:

        """

        result = self.btc_xmi_logon()
        if result.fail:
            self.logger.debug('logon to XBP interface failed {:s}/{:s}'.format(self.XBP_EXT_COMPANY,
                                                                               self.XBP_EXT_PRODUCT))
            return result

        self.logger.debug('logon to XBP interface successful')

        #        result = self.btc_xbp_variant_info_get(self, abapProgramName)
        #        if not result.fail:
        #            variants=[record['VARIANT'] for record in result.data.get('ABAP_VARIANT_TABLE')]
        #            if abapVariantName in variants:



        fmParameters = dict()
        fmParameters['ABAP_PROGRAM_NAME'] = abapProgramName
        fmParameters['ABAP_VARIANT_NAME'] = abapVariantName
        fmParameters['EXTERNAM_USER_NAME']= self.XBP_EXT_USER

        result = self.call_fm('BAPI_XBP_VARIANT_DELETE', **fmParameters)
        if result.fail:
            return result

        if result.data['RETURN']['TYPE'] == 'E':
            return Fail(message=result.data['RETURN']['MESSAGE'])
        else:
            return Result('Variant Deleted')
Example #24
0
    def btc_xbp_job_open(self, jobName):
        """ Perform BAPI_XBP_JOB_OPEN

        OSS Notes:
            1770388 - Enhancements in the XBP interface

        :param jobName:Name of the background job
        :return: Either Fail(True) or Result(jobcount)
        """
        result = self.call_fm('BAPI_XBP_JOB_OPEN', JOBNAME=jobName,
                           EXTERNAL_USER_NAME=self.XBP_EXT_USER)

        if result.fail:
            return result

        result=result.data
        if result['RETURN']['TYPE'] == 'E':
            logMessage = 'BAPI_XBP_JOB_OPEN {:s}: {:s}'.format(jobName, result['RETURN']['MESSAGE'])
            self.logger.error(logMessage)
            return Fail(message=logMessage)
        else:
            jobcount = result['JOBCOUNT']
            self.logger.debug('BAPI_XBP_JOB_OPEN successful for job %s with job count %s', jobName, str(jobcount))
            return Result(data=jobcount)
    def execute(self):

        checkobj = self.checkObject
        for parameterSet in checkobj.params:
            record = dict(
                PARAMETERSET=parameterSet.param_set_name,
                EXPECTED=parameterSet.expected_count,
                OPERATOR=self.operators.lookup(parameterSet.operator),
                INTERVAL=parameterSet.interval,
                INTERVAL_TYPE=self.INTERVALS.get(parameterSet.interval_type),
                ABAPNAME=parameterSet.abapname,
                JOBNAME=parameterSet.sel_jobname,
                JOBCOUNT=parameterSet.sel_jobcount,
                JOBGROUP=parameterSet.sel_jobgroup,
                USERNAME=parameterSet.sel_username,
                NODATE=self.boolmapper(parameterSet.sel_no_date),
                WITH_PRED=self.boolmapper(parameterSet.sel_with_pred),
                EVENTID=parameterSet.sel_eventid,
                EVENTPARA=parameterSet.sel_eventpara,
                PRELIM=self.boolmapper(parameterSet.sel_prelim),
                SCHEDUL=self.boolmapper(parameterSet.sel_schedul),
                READY=self.boolmapper(parameterSet.sel_ready),
                RUNNING=self.boolmapper(parameterSet.sel_running),
                FINISHED=self.boolmapper(parameterSet.sel_finished),
                ABORTED=self.boolmapper(parameterSet.sel_aborted),
            )

            parameters = dict()
            if parameterSet.abapname:
                parameters['ABAPNAME'] = parameterSet.abapname

            parameters['JOB_SELECT_PARAM'] = dict()
            parameters['JOB_SELECT_PARAM'][
                'JOBNAME'] = parameterSet.sel_jobname or '*'
            parameters['JOB_SELECT_PARAM'][
                'USERNAME'] = parameterSet.sel_username or '*'

            if parameterSet.sel_jobcount:
                parameters['JOB_SELECT_PARAM'][
                    'JOBCOUNT'] = parameterSet.sel_jobcount

            if parameterSet.sel_jobgroup:
                parameters['JOB_SELECT_PARAM'][
                    'JOBGROUP'] = parameterSet.sel_jobgroup

            if parameterSet.sel_no_date:
                parameters['JOB_SELECT_PARAM']['NODATE'] = self.boolmapper(
                    parameterSet.sel_no_date)

            if parameterSet.sel_with_pred:
                parameters['JOB_SELECT_PARAM']['WITH_PRED'] = self.boolmapper(
                    parameterSet.sel_with_pred)

            if parameterSet.sel_eventid:
                parameters['JOB_SELECT_PARAM'][
                    'EVENTID'] = parameterSet.sel_eventid

            if parameterSet.sel_eventpara:
                parameters['JOB_SELECT_PARAM'][
                    'EVENTPARA'] = parameterSet.sel_eventpara

            if parameterSet.sel_prelim:
                parameters['JOB_SELECT_PARAM']['PRELIM'] = self.boolmapper(
                    parameterSet.sel_prelim)

            if parameterSet.sel_schedul:
                parameters['JOB_SELECT_PARAM']['SCHEDUL'] = self.boolmapper(
                    parameterSet.sel_schedul)

            if parameterSet.sel_ready:
                parameters['JOB_SELECT_PARAM']['READY'] = self.boolmapper(
                    parameterSet.sel_ready)

            if parameterSet.sel_running:
                parameters['JOB_SELECT_PARAM']['RUNNING'] = self.boolmapper(
                    parameterSet.sel_running)

            if parameterSet.sel_finished:
                parameters['JOB_SELECT_PARAM']['FINISHED'] = self.boolmapper(
                    parameterSet.sel_finished)

            if parameterSet.sel_aborted:
                parameters['JOB_SELECT_PARAM']['ABORTED'] = self.boolmapper(
                    parameterSet.sel_aborted)

            result = self.systemConnection.systemtime
            if result.fail:
                record['CONFIGURED'] = result.fail
                record['RATING'] = 'error'
                self.actionResult.addResult(record)
                self.actionResult.rating = 'error'
                return Result(self.actionResult)

            if parameterSet.sel_from_date is None and \
                parameterSet.sel_from_time is None and \
                parameterSet.sel_to_date is None and \
                parameterSet.sel_to_time is None:

                self.logger.debug('No Time frame specified')
                basetime = result.data['localtime']
                self.logger.debug('basetime: %s', pformat(basetime))
                intervall = datecalc.getIntervalDate(
                    parameterSet.interval, parameterSet.interval_type,
                    basetime, '-')
                self.logger.debug('interval border: %s', pformat(intervall))

                parameters['JOB_SELECT_PARAM'][
                    'FROM_DATE'] = intervall.strftime("%Y%m%d")
                parameters['JOB_SELECT_PARAM']['TO_DATE'] = basetime.strftime(
                    "%Y%m%d")
                parameters['JOB_SELECT_PARAM'][
                    'FROM_TIME'] = intervall.strftime("%H%M%S")
                parameters['JOB_SELECT_PARAM']['TO_TIME'] = basetime.strftime(
                    "%H%M%S")

            self.logger.debug('Attempting Job Selection: %s',
                              pformat(parameters))
            result = self.retrieveData(**parameters)
            if not result.fail:
                downloaded_data = result.data
                record['CONFIGURED'] = len(downloaded_data['SELECTED_JOBS'])
            else:
                record['CONFIGURED'] = result.fail
                record['RATING'] = 'error'
                self.actionResult.addResult(record)
                self.actionResult.rating = 'error'
                return Result(self.actionResult)

            record = self.rateIndividualResult(record)
            self.actionResult.addResult(record)

        self.rateOverallResult()

        return Result(data=self.actionResult)
Example #26
0
    def btc_xbp_variant_create(self, abapProgramName, abapVariantName, abapVariantText, dia=None, protected=None,
                               variantInfo=None, variantInfoL=None):
        """ Create variant for ABAP program

        :param abapProgramName: str Program name
        :param abapVariantName: str variant name
        :param abapVariantText: str desciption for variant
        :param dia: batch or dialog?
        :param protected:
        :param extUserName: external xmi username
        :param variantInfo: actual data of the variant
        :param variantInfoL: data of the variant with longnr parameters
        :return:

        variantInfo and variantInfoL are internal tables that need to be specified as a list of dictionaries.
        each row consisting of these fields:

        REPORT  Report Name
        VARIANT Variant Name
        PNAME   ABAP/4: Name of SELECT-OPTION / PARAMETER
        PKIND   ABAP: Type of selection
        POLEN   ABAP: Output length of selection condition
        PTEXT   CHAR30 for SYST
        PSIGN   ABAP: ID: I/E (include/exclude values)
        POPTION ABAP: Selection option (EQ/BT/CP/...)
        PLOW    Selection variants: Field content (LOW/HIGH)
        PHIGH   Selection variants: Field content (LOW/HIGH)

        """

        result = self.btc_xmi_logon()
        if result.fail:
            self.logger.debug('logon to XBP interface failed {:s}/{:s}'.format(self.XBP_EXT_COMPANY,
                                                                               self.XBP_EXT_PRODUCT))
            return result

        self.logger.debug('logon to XBP interface successful')

#        result = self.btc_xbp_variant_info_get(self, abapProgramName)
#        if not result.fail:
#            variants=[record['VARIANT'] for record in result.data.get('ABAP_VARIANT_TABLE')]
#            if abapVariantName in variants:



        fmParameters = dict()
        fmParameters['ABAP_PROGRAM_NAME'] = abapProgramName
        fmParameters['ABAP_VARIANT_NAME'] = abapVariantName
        fmParameters['ABAP_VARIANT_TEXT'] = abapVariantText

        if dia:
            fmParameters['DIA'] = dia

        if protected:
            fmParameters['DIA'] = protected

        if variantInfoL:
            fmParameters['VARIANT_INFO_L'] = variantInfoL
        elif variantInfo:
            fmParameters['VARIANT_INFO'] = variantInfo
        else:
            return Fail('Missing Variant Information')
        result = self.call_fm('BAPI_XBP_VARIANT_CREATE', **fmParameters)
        if result.fail:
            return result

        if result.data['RETURN']['TYPE'] == 'E':
            return Fail(message=result.data['RETURN']['MESSAGE'])
        else:
            return Result('Variant Created')
Example #27
0
    def download_table(self, tabname: str, where_clause: str = None, tab_fields: list = None,
                       fetchsize: int = 1000) -> Union[Result, Fail]:
        '''Downloads a Table

        .. warning::

           This can be memory intensive and is also restricted to a line length of 512 characters,

        :param where_clause: Where clause to restrict result set in ABAP syntax
        :param tab_fields: list of fields
        :param fetchsize: number of records to retrieve
        :param tabname: Table name

        :return: Result(data={data: <list of dictionaries>, headers: <list of headers>}) or Fail(message=message)

        '''

        # TODO: Make more memory efficient
        # TODO: download records larger than 512 characters

        from pprint import pformat

        self.logger.debug('trying to download table ' + tabname)

        # Configure function module call
        fm_params = dict(QUERY_TABLE=tabname,
                         DELIMITER='|')

        if where_clause:
            n = 72  # max. length of one where clause input value.
            fm_params['OPTIONS'] = [{'TEXT': where_clause[i:i + n]} for i in range(0, len(where_clause), n)]

        if tab_fields:
            fm_params['FIELDS'] = [{'FIELDNAME': x} for x in tab_fields]
            self.logger.debug('specified table fields: {:s}'.format(pformat(fm_params['FIELDS'])))

        fm_params['ROWCOUNT'] = fetchsize

        self.logger.debug('RFC_READ_TABLE parameters: {:s}'.format(pformat(fm_params)))

        result = self.call_fm('RFC_READ_TABLE', NO_DATA='X', **fm_params)
        if result.fail:
            return result

        fm_tbl_fields = result.data['FIELDS']  # this will contain the table definition including field length.

        fm_tbl_headers = [x['FIELDNAME'] for x in fm_tbl_fields]
        record_size = sum([int(x['LENGTH']) for x in fm_tbl_fields])
        self.logger.debug('Record Size: {:d}'.format(record_size))

        if record_size > 512:
            message = 'requested column length of {:d} is larger than maximum possible (512)'.format(record_size)
            self.logger.error(message)
            return Fail(message=message, data=fm_tbl_fields)

        iteration = 0
        recordcounter = 1

        table_data = []

        while recordcounter > 0:
            self.logger.debug(
                'starting function module RFC_READ_TABLE with data retrieval. Iteration: {:d}'.format(iteration))
            rowskips = iteration * fetchsize
            fm_params['ROWSKIPS'] = rowskips
            result = self.call_fm('RFC_READ_TABLE', **fm_params)
            if result.fail:
                return result

            data = result.data['DATA']
            if len(data) > 0:
                self.logger.debug(
                    'generating result set from returned records. fetchsize={:d}, iteration={:d}'.format(fetchsize,
                                                                                                         iteration))
                for row in data:
                    splitRow = row['WA'].strip().split('|')
                    splitRow = [x.strip() for x in splitRow]
                    record = dict(zip(fm_tbl_headers, splitRow))
                    table_data.append(record)
            else:
                recordcounter = 0
                if iteration == 0:
                    return Result(data={'data': [], 'headers': fm_tbl_headers})
            iteration += 1
        else:
            return Result(data={'data': table_data, 'headers': fm_tbl_headers})
Example #28
0
    def execute(self, connection, **kwargs):
        """ Verifies the system parameters according to config file.

        :param credentials: profile parameter to be checked.

        """

        paramkeys = {item.upper() for item in self.actionResult['Parameters']}
        result = connection.fm_interface(self.FM)
        if result.fail:
            self.actionResult.rating = 'error'

        self.actionResult.rating = 'info'
        fm_interface = result.data

        fmkeys = {item['PARAMETER'] for item in fm_interface['PARAMS']}

        relevantParams = paramkeys & fmkeys

        fmcallparams = {}

        for parameter in relevantParams:

            param_value = self.actionResult['Parameters'].get(parameter,
                                                              raw=True)
            if param_value == '':
                param_value = ' '

            fmcallparams[parameter] = param_value

        self.logger.debug('parameters for SUIM API Call: %s',
                          pformat(fmcallparams))

        result = connection.call_fm(self.FM, **fmcallparams)

        if result.fail:
            raise SystemError

        fm_data = result.data

        message = 'The plugin showed some additional results: \n'

        #Analyzing the return structure
        return_data = fm_data.get('RETURN')
        if len(return_data) > 0:
            msg_types = [item['TYPE'] for item in return_data]
            for rec in return_data:
                message += '{}: {}\n'.format(
                    self.BAPI_MSG_TYPES[rec.get('TYPE')], rec['MESSAGE'])

            self.actionResult.message = message
            if 'E' in msg_types or 'A' in msg_types:
                self.actionResult.rating = 'error'
            elif 'W' in msg_types:
                self.actionResult.rating = 'warning'

        self.actionResult.result = fm_data.get(self.RETURNSTRUCTURE)

        if len(self.actionResult.result) > 0:
            self.actionResult.rating = 'fail'
        else:
            self.actionResult.rating = 'pass'

        return Result(data=self.actionResult)
Example #29
0
def importCheck(filename, session=None, format='yaml'):
    """ Import Checks

    :param filename: Name of the file that should get imported
    :param session: The session that should be used for importing the export
    :param format: The of the file
    """
    logger.debug('Importing Check from file %s', filename)

    try:
        data = readChecksYaml(filename)
    except Exception as err:
        return Fail(
            message='Error reading Checks file: {}'.format(pformat(err)))

    if session is None:
        session = systemcheck.session.SESSION

    try:
        result = buildSaObject(data['object'])
    except Exception as err:
        logger.exception(err)
        return Fail(message='Error When Creating Check object: ' +
                    pformat(err))

    if result.fail:
        return result

    checkNode = result.data

    #Now we need to build the tree structure

    node = systemcheck.utils.get_or_create(
        session, model=systemcheck.checks.models.Check, parent_id=None)

    logger.debug('Building Tree Structure for %s',
                 pformat(data.get('treepath')))

    for level, branch in enumerate(data.get('treepath')):
        name = branch.get('name')
        saClassname = branch.get('type')
        description = branch.get('description')
        logger.debug('Level: %s, Name: %s, Class: %s', str(level), name,
                     saClassname)

        saClass = models.get_class_by_name(models.meta.Base, saClassname)

        nodeFound = False

        for child in node.children:
            if isinstance(child, saClass) and child.name == branch.get('name'):
                logger.debug('Found existing node "%s" ', name)
                node = child
                nodeFound = True
                break

        if not nodeFound:
            logger.debug(
                'Node with name %s and class %s does not exist. Create new',
                name, saClassname)
            node = saClass(name=name,
                           description=description,
                           parent_node=node)

    models.meta.base.Base.metadata.create_all(session.bind)

    try:
        session.commit()
    except Exception as err:
        return Fail(message='Error During Import: '.format(pformat(err)))

    # Finally, adding the object to the tree

    node.children.append(checkNode)

    try:
        session.commit()
    except Exception as err:
        return Fail(message='Error During Import: '.format(pformat(err)))

    return Result(data=checkNode)
Example #30
0
def buildSaObject(saData: dict, saClass=None):
    """ Build a SQLAlchemy Object from the retrieved dictionary


    :param saData: The dictionary representation of the Object
    :param saClass: a hint for the recursive processing to provide a correct class """

    logger.debug('building sqlalchemy object from data: %s')

    params = dict()

    if saClass is None:
        logger.debug('No Class Specified, determine class')
        saClassName = saData.get('type')
        saClass = models.get_class_by_name(models.meta.Base, saClassName)

    for key, value in saData.items():
        if not isinstance(value, list):
            # Lists are lists of other SQLAlchemy models. We need to ignore them when instantiating for the first time
            params[key] = value

    logger.debug('Parameter to instantiate SQLAlchemy Object: %s',
                 pformat(params))

    try:
        saObject = saClass(**params)
    except Exception as err:
        logger.exception(err)
        return Fail(message='Error Building SQLAlchemy Object', data=err)

    for key, value in saData.items():
        if isinstance(value, list):
            logger.debug('%s is a list', key)
            for subitem in value:
                if key == 'params':
                    # Parameters do not inherit from the Checks tree, but are simple references. In this case, the name
                    # of the class is the parent's class name with '__params' as suffix.
                    newClassName = saClassName + '__params'
                    logger.debug('Class name of key %s is %s', key,
                                 newClassName)
                elif key == 'restrictions':
                    # Similar to parameters, restrictions do not inherit from the Checks tree either. In this case, the name
                    # of the class is the parent's class name with '__restrictions' as suffix.
                    newClassName = saClassName + '__restrictions'
                    logger.debug('Class name of key %s is %s', key,
                                 newClassName)
                else:
                    newClassName = subitem.get('type')

                if newClassName is not None:
                    newClass = systemcheck.models.utils.get_class_by_name(
                        models.meta.Base, newClassName)

                    result = buildSaObject(subitem, newClass)
                    if result.fail:
                        return result

                    newObject = result.data
                    getattr(saObject, key).append(newObject)
                else:
                    logger.error(
                        'Class Name for attribute %s could notbe determined (%s)',
                        key, pformat(subitem))

    return Result(message='SQLAlchem Object Built', data=saObject)