예제 #1
0
 def wrap(*args, **kwargs):
     current_time = time.time()
     body = func(*args, **kwargs)
     duration = time.time() - current_time
     body['duration'] = duration
     json_body = json.dumps(body)
     return json.loads(json_body)
예제 #2
0
 def __init__(self,
              body,
              content_type='application/json',
              status_code=200,
              charset='UTF-8'):
     headers = _get_headers(content_type, charset=charset)
     self['statusCode'] = status_code
     self['headers'] = headers
     if isinstance(body, dict):
         self['body'] = json.dumps(body,
                                   default=lambda o: '<not serializable>')
     else:
         self['body'] = body
     self['isBase64Encoded'] = False
예제 #3
0
 def do_POST(self):
     content_length = int(
         self.headers['Content-Length'])  # <--- Gets the size of data
     post_data = self.rfile.read(
         content_length)  # <--- Gets the data itself
     # logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
     #         str(self.path), str(self.headers), post_data.decode('utf-8'))
     body = post_data.decode('utf-8')
     body_json = json.loads(body)
     client_address = None
     if self.client_address:
         client_address = self.client_address[0]
     response = abstracted_gateway(body_json, {},
                                   resource,
                                   client_ip=client_address)
     json_response = json.dumps(response)
     json_response = json_response.encode('utf-8')
     self._set_response()
     self.wfile.write(json_response)
예제 #4
0
def do(data, resource):
    partition = 'logic-function'
    body = {}
    params = data['params']
    user = data.get('user', None)

    function_name = params.get('function_name')
    payload = params.get('payload')
    show_traceback = params.get('show_traceback', False)
    # logging = params.get('logging', False)

    items, _ = resource.db_query(partition, [{'option': None, 'field': 'function_name', 'value': function_name, 'condition': 'eq'}], reverse=True)

    if len(items) == 0:
        body['error'] = error.NO_SUCH_FUNCTION
        return body
    else:
        item = items[0]

        zip_file_id = item['zip_file_id']
        requirements_zip_file_id = item.get('requirements_zip_file_id', None)
        function_handler = item['handler']
        use_traceback = item.get('use_traceback', False)
        use_logging = item.get('use_logging', False)
        sdk_config = item.get('sdk_config', {})
        use_standalone = item.get('use_standalone', False)
        function_version = item.get('function_version', False)

        function_package = '.'.join(function_handler.split('.')[:-1])
        function_method = function_handler.split('.')[-1]
        function_name_as_random = 'fn{}'.format(uuid.uuid4()).replace('-', '')

        zip_temp_dir = get_cache(zip_file_id, 'zip_temp_dir')
        extracted_dir = get_cache(zip_file_id, 'extracted_dir')

        if use_standalone:
            request_body = {
                'payload': payload,
                'user': user,
                'handler': function_handler,
                'show_traceback': show_traceback and use_traceback
            }
            response = resource.function_execute_stand_alone_function(f'{function_name}_{function_version}', request_body)
            return response  # TODO

        if (zip_temp_dir is None) or (extracted_dir is None):
            zip_file_bin = resource.file_download_bin(zip_file_id)
            zip_temp_dir = tempfile.mktemp()
            extracted_dir = tempfile.mkdtemp()

            with open(zip_temp_dir, 'wb') as zip_temp:
                zip_temp.write(zip_file_bin)

            # Extract function files and copy configs
            with ZipFile(zip_temp_dir) as zip_file:
                zip_file.extractall(extracted_dir)
                copy_configfile(extracted_dir, sdk_config)

            # Extract requirements folders and files
            try:
                if requirements_zip_file_id:
                    requirements_zip_temp_dir = tempfile.mktemp()
                    requirements_zip_file_bin = resource.file_download_bin(requirements_zip_file_id)
                    with open(requirements_zip_temp_dir, 'wb') as zip_temp:
                        zip_temp.write(requirements_zip_file_bin)
                    with ZipFile(requirements_zip_temp_dir) as zip_temp:
                        zip_temp.extractall(extracted_dir)
            except Exception as ex:
                pass

        virtual_handler = 'virtual_handler{}.py'.format(uuid.uuid4())
        virtual_handler_path = os.path.join(extracted_dir, virtual_handler)
        vh_code = "#!/usr/bin/python\n" + \
                  "# -*- coding: utf-8 -*-\n" + \
                  "import io\n" + \
                  "import json\n" + \
                  "import traceback\n" + \
                  "from contextlib import redirect_stdout\n" +\
                  "if __name__ == '__main__':\n" +\
                  "    std_str = io.StringIO()\n" +\
                  "    with redirect_stdout(std_str):\n" + \
                  "        resp, error = None, None\n" + \
                  "        try:\n" + \
                  "            from {} import {} as {}".format(function_package, function_method, function_name_as_random) + '\n' + \
                  "            resp = {}({}, {})\n".format(function_name_as_random, payload, json.loads(json.dumps(user))) +\
                  "        except Exception as e:\n" +\
                  "            error = traceback.format_exc()\n" +\
                  '    print(json.dumps({\"response\": resp, \"stdout\": std_str.getvalue(), \"error\": error}, default=lambda o: \"<not serializable>\"))\n'
        with open(virtual_handler_path, 'w+') as vh:
            vh.write(vh_code)

        return_value = {}
        try:
            return_value = run_subprocess(virtual_handler_path)

            if return_value:
                return_value = json.loads(return_value)
            else:
                return_value = {}

            body['response'] = return_value.get('response', None)
            body['stdout'] = return_value.get('stdout', None)
            err = return_value.get('error', None)
            if err:
                if use_traceback and show_traceback:
                    body['traceback'] = err
                r = slack.send_system_slack_message(resource, str(body).replace('\\', ''))
                print('slack response:', r)

        except Exception as ex:
            error_traceback = None  # traceback.format_exc()
            body['error'] = error.FUNCTION_ERROR
            body['error']['message'] = body['error']['message'].format('{}, {}, {}'.format(ex, error_traceback, return_value))
            r = slack.send_system_slack_message(resource, str(body).replace('\\', ''))
            print('slack response:', r)

        # os.remove(zip_temp_dir)
        # shutil.rmtree(extracted_dir, ignore_errors=True)
        os.remove(virtual_handler_path)
        put_cache(zip_file_id, 'zip_temp_dir', zip_temp_dir)
        put_cache(zip_file_id, 'extracted_dir', extracted_dir)

        # Logging
        if use_logging:
            content = json.dumps({
                'params': params,
                'body': body,
            })
            content = content[:1000 * 1000 * 2]
            create_event(resource, user, 'run_function:{}'.format(function_name), content, 'logic')

        return body
예제 #5
0
def do(data, resource):
    partition = 'logic-function'
    body = {}
    params = data['params']
    user = data.get('user', None)

    function_name = params.get('function_name')
    payload = params.get('payload')

    items, _ = resource.db_query(partition, [{
        'option': None,
        'field': 'function_name',
        'value': function_name,
        'condition': 'eq'
    }])

    if len(items) == 0:
        body['error'] = error.NO_SUCH_FUNCTION
        return body
    else:
        item = items[0]

        zip_file_id = item['zip_file_id']
        requirements_zip_file_id = item.get('requirements_zip_file_id', None)
        function_handler = item['handler']
        sdk_config = item.get('sdk_config', {})
        function_package = '.'.join(function_handler.split('.')[:-1])
        function_method = function_handler.split('.')[-1]

        zip_file_bin = resource.file_download_bin(zip_file_id)

        zip_temp_dir = tempfile.mktemp()

        extracted_dir = tempfile.mkdtemp()

        with open(zip_temp_dir, 'wb') as zip_temp:
            zip_temp.write(zip_file_bin)

        # Extract function files and copy configs
        with ZipFile(zip_temp_dir) as zip_file:
            zip_file.extractall(extracted_dir)
            copy_configfile(extracted_dir, sdk_config)

        # Extract requirements folders and files
        if requirements_zip_file_id:
            requirements_zip_temp_dir = tempfile.mktemp()
            requirements_zip_file_bin = resource.file_download_bin(
                requirements_zip_file_id)
            with open(requirements_zip_temp_dir, 'wb') as zip_temp:
                zip_temp.write(requirements_zip_file_bin)
            with ZipFile(requirements_zip_temp_dir) as zip_temp:
                zip_temp.extractall(extracted_dir)

        try:
            #  Comment removing cache because of a performance issue
            #  invalidate_caches()
            sys.path.insert(0, extracted_dir)
            module = import_module(function_package)
            std_str = io.StringIO()
            with redirect_stdout(std_str):
                handler = getattr(module, function_method)
                body['response'] = handler(payload, user)
            body['stdout'] = std_str.getvalue()
        except Exception as ex:
            body['error'] = error.FUNCTION_ERROR
            body['error']['message'] = body['error']['message'].format(ex)
        os.remove(zip_temp_dir)

        # Logging
        create_event(resource, user, 'run_function:{}'.format(function_name),
                     json.dumps({
                         'params': params,
                         'body': body,
                     }), 'logic')

        return body
예제 #6
0
 def __init__(self, body, content_type='application/json', status_code=200):
     headers = _get_headers(content_type)
     self['statusCode'] = status_code
     self['headers'] = headers
     self['body'] = json.dumps(body)
     self['isBase64Encoded'] = False