def test_list_config(self):
     self.set_config('upstream-service', UPSTREAM_SERVICE)
     token = self.token_for(ENV, USER_CLASS)
     try:
         api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
         expected = {
             "external-url": "https://ci.kbase.us/services/ee2",
             "kbase-endpoint": "https://ci.kbase.us/services",
             "workspace-url": "https://ci.kbase.us/services/ws",
             "catalog-url": "https://ci.kbase.us/services/catalog",
             "shock-url": "https://ci.kbase.us/services/shock-api",
             "handle-url": "https://ci.kbase.us/services/handle_service",
             "srv-wiz-url": "https://ci.kbase.us/services/service_wizard",
             "auth-service-url":
                 "https://ci.kbase.us/services/auth/api/legacy/KBase/Sessions/Login",
             "auth-service-url-v2": "https://ci.kbase.us/services/auth/api/V2/token",
             "auth-service-url-allow-insecure": "false",
             "scratch": "/kb/module/work/tmp",
             "executable": "execute_runner.sh",
             "docker_timeout": "604805",
             "initialdir": "/condor_shared",
             "transfer_input_files": "/condor_shared/JobRunner.tgz"
         }
         config = api.list_config()
         self.assertEqual(config, expected)
     except Exception as ex:
         self.assert_no_exception(ex)
예제 #2
0
 def cancel_job(self, params):
     api = EE2Api(url=self.config['ee2-url'],
                  token=self.token,
                  timeout=self.timeout)
     admin = params.get('admin', False)
     if admin:
         as_admin = 1
         terminated_code = params.get('code', 1)
     else:
         as_admin = 0
         terminated_code = params.get('code', 0)
     try:
         api.cancel_job({
             'job_id': params['job_id'],
             'terminated_code': terminated_code,
             'as_admin': as_admin
         })
         return {'canceled': True}
     except ServiceError as se:
         if re.search(('A job with status .+ cannot be terminated. '
                       'It is already cancelled.'), se.message):
             return {'canceled': False}
         elif re.search('Cannot find job with ids:', se.message):
             raise ServiceError(
                 code=10,
                 message="The job specified for cancelation does not exist",
                 data={'job_id': params['job_id']})
         else:
             raise se
예제 #3
0
 def is_admin(self):
     api = EE2Api(url=self.config['ee2-url'],
                  token=self.token,
                  timeout=self.timeout)
     result = api.is_admin()
     if result == 1:
         return True
     else:
         return False
 def test_status(self):
     self.set_config('upstream-service', UPSTREAM_SERVICE)
     token = self.token_for(ENV, USER_CLASS)
     try:
         api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
         status = api.status()
         self.assertEqual(status['version'], '0.0.1')
         self.assertEqual(status['service'], 'KBase Execution Engine')
         self.assertIsInstance(status['server_time'], float)
         self.assertIsInstance(status['git_commit'], str)
     except Exception as ex:
         self.assert_no_exception(ex)
    def test_get_admin_permission_admin(self):
        self.set_config('upstream-service', UPSTREAM_SERVICE)
        token = self.token_for(ENV, 'admin')
        schema = Schema(schema_dir="ee2_api", load_schemas=True)
        try:
            api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
            result = api.get_admin_permission()
            schema.validate('get_admin_permission', result)
            self.assertEqual(result['permission'], 'w')

        except Exception as ex:
            self.assert_no_exception(ex)
    def test_is_admin_is_not(self):
        self.set_config('upstream-service', UPSTREAM_SERVICE)
        token = self.token_for(ENV, USER_CLASS)
        schema = Schema(schema_dir="ee2_api", load_schemas=True)
        try:
            api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
            result = api.is_admin()
            schema.validate('is_admin', result)
            self.assertEqual(result, False)

        except Exception as ex:
            self.assert_no_exception(ex)
 def test_ver(self):
     self.set_config('upstream-service', UPSTREAM_SERVICE)
     token = self.token_for(ENV, USER_CLASS)
     # impl, context = self.impl_for(ENV, USER_CLASS)
     # params = {
     #     'job_ids': [JOB_ID_HAPPY],
     #     'timeout': TIMEOUT
     # }
     try:
         api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
         version = api.ver()
         self.assertEqual(version, '0.0.1')
     except Exception as ex:
         self.assert_no_exception(ex)
    def test_check_jobs(self):
        self.set_config('upstream-service', UPSTREAM_SERVICE)
        token = self.token_for(ENV, USER_CLASS)
        schema = Schema(schema_dir="ee2_api", load_schemas=True)
        try:
            api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
            params = {
                'job_ids': [JOB_ID_HAPPY]
            }
            jobs = api.check_jobs(params)
            schema.validate('check_jobs', jobs)
            self.assertEqual(jobs['job_states'][0]['user'], 'kbaseuitest')

        except Exception as ex:
            self.assert_no_exception(ex)
    def test_get_job_logs(self):
        self.set_config('upstream-service', UPSTREAM_SERVICE)
        token = self.token_for(ENV, USER_CLASS)
        schema = Schema(schema_dir="ee2_api", load_schemas=True)
        try:
            api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
            params = {
                'job_id': JOB_ID_LOG_HAPPY
            }
            result = api.get_job_logs(params)
            schema.validate('get_job_logs', result)
            self.assertEqual(result['lines'][0]['ts'], 1585858534288)

        except Exception as ex:
            self.assert_no_exception(ex)
    def test_check_job_canceled(self):
        self.set_config('upstream-service', UPSTREAM_SERVICE)
        token = self.token_for(ENV, USER_CLASS)
        schema = Schema(schema_dir="ee2_api", load_schemas=True)
        try:
            api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
            params = {
                'job_id': JOB_ID_HAPPY
            }
            result = api.check_job_canceled(params)
            schema.validate('check_job_canceled', result)
            self.assertEqual(result['canceled'], False)

        except Exception as ex:
            self.assert_no_exception(ex)
예제 #11
0
    def get_job_log(self, params):
        job_id = get_param(params, 'job_id')
        offset = get_param(params, 'offset')
        limit = get_param(params, 'limit')
        # search = params.get('search')
        # level = params.get('level')
        if params.get('admin', False):
            as_admin = 1
        else:
            as_admin = 0

        api = EE2Api(url=self.config['ee2-url'],
                     token=self.token,
                     timeout=self.timeout)
        try:
            # Note plural form of get_job_log. The upstream apis (njs, ee2 copying it)
            # mistakenly use the plural form ... it is a log of a job, not a logs of a job.
            result = api.get_job_logs({
                'job_id': job_id,
                'offset': offset,
                'limit': limit,
                'as_admin': as_admin
            })
        except ServiceError as se:
            # handle specific error mesages
            if se.code == -32000:
                if re.search('Cannot find job log with id[s]?:', se.message):
                    return {'log': [], 'total_count': 0}
                    # raise ServiceError(
                    #     code=30,
                    #     message='The requested job log could not be found',
                    #     data={
                    #         'job_id': job_id
                    #     })
            raise se
        else:
            entries = [
                raw_log_line_to_entry(line, index, offset)
                for index, line in enumerate(result['lines'])
            ]

            if limit is not None:
                entries = entries[slice(0, limit)]

            # entries = list(map(raw_log_line_to_entry, result['lines']))
            return {'log': entries, 'total_count': result['count']}
    def test_check_jobs_date_range_for_all(self):
        self.set_config('upstream-service', UPSTREAM_SERVICE)
        token = self.token_for(ENV, 'admin')
        schema = Schema(schema_dir="ee2_api", load_schemas=True)
        try:
            api = EE2Api(self.get_config('ee2-url'), token, TIMEOUT)
            params = {
                'start_time': START_TIME_1,
                'end_time': END_TIME_1,
                'user': USER,
                'offset': 0,
                'limit': 10
            }
            result = api.check_jobs_date_range_for_all(params)
            schema.validate('check_jobs_date_range_for_all', result)
            self.assertEqual(result['jobs'][0]['job_id'], '54b02da8e4b06e6b5555476d')

        except Exception as ex:
            self.assert_no_exception(ex)
예제 #13
0
    def ee2_get_jobs(self, params):
        api = EE2Api(url=self.config['ee2-url'],
                     token=self.token,
                     timeout=self.timeout)
        if params.get('admin', False):
            as_admin = 1
        else:
            as_admin = 0

        try:
            jobs = api.check_jobs({
                'job_ids': params['job_ids'],
                'as_admin': as_admin
            })
            return jobs['job_states']
        except ServiceError as se:
            if se.code == -32000:
                if re.search('Cannot find job with ids:', se.message):
                    # Hmm, wonder if the missing job ids are returned in the exception?
                    raise ServiceError(code=10,
                                       message='Job not found',
                                       data={'message': se.message})
                else:
                    raise ServiceError(code=1,
                                       message='Unknown error occurred',
                                       data={
                                           'upstream_error': {
                                               'code': se.code,
                                               'message': se.message,
                                               'data': se.data
                                           }
                                       })
            else:
                raise
        except Exception as ex:
            raise ServiceError(code=1,
                               message='Unknown error',
                               data={'original_message': str(ex)})
from JobBrowserBFF.model.EE2Api import EE2Api
import os
import json
import datetime
import time
import math

url = 'https://ci.kbase.us/services/ee2'
token = os.environ['KBASE_TOKEN']
client = EE2Api(url=url, token=token, timeout=60)
version = client.ver()
print('VERSION')
print(version)

START_TIME = 0  # 1970/1/1
END_TIME = 1609459200000  # 2021/1/1
BATCH_SIZE = 1000


def save_job(data, iter):
    job_id = data['job']['job_id']
    with open('temp/drift/{}-{:03d}.json'.format(job_id, iter), 'w') as f:
        f.write(json.dumps(data, indent=4))


def get_last_job():
    # get first batch
    params = {
        'start_time': START_TIME,
        'end_time': END_TIME,
        'offset': 0,
예제 #15
0
    def ee2_query_jobs(self,
                       offset,
                       limit,
                       time_span=None,
                       search=None,
                       filter=None,
                       sort=None,
                       admin=False):
        # TODO: timeout global or timeout per call?
        api = EE2Api(url=self.config['ee2-url'],
                     token=self.token,
                     timeout=self.timeout)

        params = {
            'start_time': time_span['from'],
            'end_time': time_span['to'],
            'offset': offset,
            'limit': limit
        }

        if filter is not None:
            raw_query = []

            status = filter.get('status', [])
            if len(status) > 0:
                status_transform = {
                    'create': 'created',
                    'queue': 'queued',
                    'run': 'running',
                    'complete': 'completed',
                    'error': 'error',
                    'terminate': 'terminated'
                }
                # value = list(map(lambda x: status_transform.get(x, x), value))
                status = [status_transform.get(x, x) for x in status]
                raw_query.append({'status': {'$in': status}})

            # parse and reformat the filters...
            workspace_id = filter.get('workspace_id', [])
            if len(workspace_id) > 0:
                raw_query.append({'wsid': {'$in': workspace_id}})

            user = filter.get('user', [])
            if len(user) > 0:
                raw_query.append({'user': {'$in': user}})

            client_group = filter.get('client_group', [])
            if len(client_group) > 0:
                raw_query.append({
                    'job_input.requirements.clientgroup': {
                        '$in': client_group
                    }
                })

            app_id = filter.get('app_id', [])
            if len(app_id) > 0:
                raw_query.append({'job_input.app_id': {'$in': app_id}})

            app_module = filter.get('app_module', [])
            if len(app_module) > 0:
                raw_query.append({
                    '$or': [{
                        'job_input.app_id': {
                            '$regex': f'^{module_name}/',
                            '$options': 'i'
                        }
                    } for module_name in app_module]
                })

            app_function = filter.get('app_function', [])
            if len(app_function) > 0:
                raw_query.append({
                    '$or': [{
                        'job_input.app_id': {
                            '$regex': f'/{function_name}$',
                            '$options': 'i'
                        }
                    } for function_name in app_function]
                })

            # wrap it in a raw query for mongoengine
            # TODO: upstream ee2 service should not be exposed like this!
            if len(raw_query) > 0:
                filter_query = {'__raw__': {'$and': raw_query}}

                params['filter'] = filter_query

        if sort is not None:
            # sort specs are not supported for ee2 (for now)
            # rather sorting is always by created timestamp
            # defaulting to ascending but reversable with the
            # ascending parameter set to 0.
            if len(sort) == 0:
                pass
            elif len(sort) > 1:
                raise ServiceError(code=40000,
                                   message="Only one sort spec supported",
                                   data={})
            elif sort[0].get('key') != 'created':
                raise ServiceError(
                    code=40000,
                    message="The sort spec must be for the 'created' key")

            if sort[0].get('direction') == 'ascending':
                ascending = 1
            else:
                ascending = 0
            params['ascending'] = ascending

        try:
            if admin:
                result = api.check_jobs_date_range_for_all(params)
            else:
                result = api.check_jobs_date_range_for_user(params)
            return result['jobs'], result['query_count']
        except ServiceError:
            raise
        except Exception as ex:
            raise ServiceError(code=40000,
                               message='Unknown error',
                               data={'original_message': str(ex)})
예제 #16
0
 def get_client_groups(self):
     api = EE2Api(url=self.config['ee2-url'],
                  token=self.token,
                  timeout=self.timeout)
     result = api.get_client_groups()
     return {'client_groups': result}