def update_apigateway(method, path, data, headers, response=None, return_forward_info=False): if return_forward_info: regex1 = r'^/restapis/[A-Za-z0-9\-]+/deployments$' if method == 'POST' and re.match(regex1, path): # this is a request to deploy the API gateway, simply return HTTP code 200 return 200 regex2 = r'^/restapis/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)/%s/([^/]+)$' % PATH_USER_REQUEST if method == 'POST' and re.match(regex2, path): api_id = re.search(regex2, path).group(1) sub_path = '/%s' % re.search(regex2, path).group(3) integration = aws_stack.get_apigateway_integration( api_id, method, sub_path) template = integration['requestTemplates'][APPLICATION_JSON] new_request = aws_stack.render_velocity_template(template, data) # forward records to our main kinesis stream # TODO check whether the target of this API method is 'kinesis' headers = aws_stack.mock_aws_request_headers(service='kinesis') headers['X-Amz-Target'] = KINESIS_ACTION_PUT_RECORDS result = common.make_http_request(url=TEST_KINESIS_URL, method='POST', data=new_request, headers=headers) return 200 return True
def update_apigateway(method, path, data, headers, response=None, return_forward_info=False): if return_forward_info: regex1 = r'^/restapis/[A-Za-z0-9\-]+/deployments$' if method == 'POST' and re.match(regex1, path): # this is a request to deploy the API gateway, simply return HTTP code 200 return 200 regex2 = r'^/restapis/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)/%s/([^/]+)$' % PATH_USER_REQUEST if method == 'POST' and re.match(regex2, path): api_id = re.search(regex2, path).group(1) sub_path = '/%s' % re.search(regex2, path).group(3) integration = aws_stack.get_apigateway_integration( api_id, method, sub_path) if integration['type'] == 'AWS': if integration['uri'].endswith('kinesis:action/PutRecords'): template = integration['requestTemplates'][ APPLICATION_JSON] new_request = aws_stack.render_velocity_template( template, data) # forward records to target kinesis stream headers = aws_stack.mock_aws_request_headers( service='kinesis') headers['X-Amz-Target'] = KINESIS_ACTION_PUT_RECORDS result = common.make_http_request(url=TEST_KINESIS_URL, method='POST', data=new_request, headers=headers) return result else: LOGGER.warning( 'API Gateway action uri "%s" not yet implemented' % integration['uri']) else: LOGGER.warning( 'API Gateway integration type "%s" not yet implemented' % integration['type']) return 200 return True
def update_apigateway(method, path, data, headers, response=None, return_forward_info=False): if return_forward_info: regex2 = r'^/restapis/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)/%s/([^/]*)$' % PATH_USER_REQUEST if re.match(regex2, path): search_match = re.search(regex2, path) api_id = search_match.group(1) sub_path = '/%s' % search_match.group(3) try: integration = aws_stack.get_apigateway_integration( api_id, method, sub_path) except Exception as e: msg = ('API Gateway endpoint "%s" for method "%s" not found' % (path, method)) LOGGER.warning(msg) return make_error(msg, 404) if method == 'POST' and integration['type'] == 'AWS': if integration['uri'].endswith('kinesis:action/PutRecords'): template = integration['requestTemplates'][ APPLICATION_JSON] new_request = aws_stack.render_velocity_template( template, data) # forward records to target kinesis stream headers = aws_stack.mock_aws_request_headers( service='kinesis') headers['X-Amz-Target'] = KINESIS_ACTION_PUT_RECORDS result = common.make_http_request(url=TEST_KINESIS_URL, method='POST', data=new_request, headers=headers) return result else: msg = 'API Gateway action uri "%s" not yet implemented' % integration[ 'uri'] LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'HTTP': function = getattr(requests, method.lower()) if isinstance(data, dict): data = json.dumps(data) result = function(integration['uri'], data=data, headers=headers) return result else: msg = ( 'API Gateway integration type "%s" for method "%s" not yet implemented' % (integration['type'], method)) LOGGER.warning(msg) return make_error(msg, 404) return 200 return True
def forward_request(self, method, path, data, headers): data = data and json.loads(data) # Paths to match regex2 = r'^/restapis/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)/%s/(.*)$' % PATH_USER_REQUEST if re.match(regex2, path): search_match = re.search(regex2, path) api_id = search_match.group(1) relative_path = '/%s' % search_match.group(3) try: integration = aws_stack.get_apigateway_integration( api_id, method, path=relative_path) assert integration except Exception: # if we have no exact match, try to find an API resource that contains path parameters path_map = get_rest_api_paths(rest_api_id=api_id) extracted_path, resource = get_resource_for_path( path=relative_path, path_map=path_map) or {} integrations = resource.get('resourceMethods', {}) integration = integrations.get(method, {}) integration = integration.get('methodIntegration') if not integration: if method == 'OPTIONS' and 'Origin' in headers: # default to returning CORS headers if this is an OPTIONS request return get_cors_response(headers) return make_error( 'Unable to find integration for path %s' % path, 404) uri = integration.get('uri') if method == 'POST' and integration['type'] == 'AWS': if uri.endswith('kinesis:action/PutRecords'): template = integration['requestTemplates'][ APPLICATION_JSON] new_request = aws_stack.render_velocity_template( template, data) # forward records to target kinesis stream headers = aws_stack.mock_aws_request_headers( service='kinesis') headers[ 'X-Amz-Target'] = kinesis_listener.ACTION_PUT_RECORDS result = common.make_http_request(url=TEST_KINESIS_URL, method='POST', data=new_request, headers=headers) return result else: msg = 'API Gateway action uri "%s" not yet implemented' % uri LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'AWS_PROXY': if uri.startswith( 'arn:aws:apigateway:') and ':lambda:path' in uri: func_arn = uri.split(':lambda:path')[1].split( 'functions/')[1].split('/invocations')[0] data_str = json.dumps(data) if isinstance(data, dict) else data try: path_params = extract_path_params( path=relative_path, extracted_path=extracted_path) except Exception: path_params = {} result = lambda_api.process_apigateway_invocation( func_arn, relative_path, data_str, headers, path_params=path_params, method=method, resource_path=path) response = Response() parsed_result = result if isinstance( result, dict) else json.loads(result) parsed_result = common.json_safe(parsed_result) response.status_code = int( parsed_result.get('statusCode', 200)) response.headers.update(parsed_result.get('headers', {})) try: response_body = parsed_result['body'] response._content = json.dumps(response_body) except Exception: response._content = '{}' return response else: msg = 'API Gateway action uri "%s" not yet implemented' % uri LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'HTTP': function = getattr(requests, method.lower()) if isinstance(data, dict): data = json.dumps(data) result = function(integration['uri'], data=data, headers=headers) return result else: msg = ( 'API Gateway integration type "%s" for method "%s" not yet implemented' % (integration['type'], method)) LOGGER.warning(msg) return make_error(msg, 404) return 200 if re.match(PATH_REGEX_AUTHORIZERS, path): return handle_authorizers(method, path, data, headers) return True
def forward_request(self, method, path, data, headers): regex2 = r'^/restapis/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)/%s/(.*)$' % PATH_USER_REQUEST if re.match(regex2, path): search_match = re.search(regex2, path) api_id = search_match.group(1) path = '/%s' % search_match.group(3) try: integration = aws_stack.get_apigateway_integration(api_id, method, path) except Exception as e: msg = ('API Gateway endpoint "%s" for method "%s" not found' % (path, method)) LOGGER.warning(msg) return make_error(msg, 404) uri = integration.get('uri') if method == 'POST' and integration['type'] in ['AWS']: if uri.endswith('kinesis:action/PutRecords'): template = integration['requestTemplates'][APPLICATION_JSON] new_request = aws_stack.render_velocity_template(template, data) # forward records to target kinesis stream headers = aws_stack.mock_aws_request_headers(service='kinesis') headers['X-Amz-Target'] = kinesis_listener.ACTION_PUT_RECORDS result = common.make_http_request(url=TEST_KINESIS_URL, method='POST', data=new_request, headers=headers) return result else: msg = 'API Gateway action uri "%s" not yet implemented' % uri LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'AWS_PROXY': if uri.startswith('arn:aws:apigateway:') and ':lambda:path' in uri: func_arn = uri.split(':lambda:path')[1].split('functions/')[1].split('/invocations')[0] data_str = json.dumps(data) if isinstance(data, dict) else data result = lambda_api.process_apigateway_invocation(func_arn, path, data_str, headers) response = Response() parsed_result = json.loads(result) response.status_code = int(parsed_result['statusCode']) response.headers.update(parsed_result['headers']) response_body = parsed_result['body'] response._content = json.dumps(response_body) return response else: msg = 'API Gateway action uri "%s" not yet implemented' % uri LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'HTTP': function = getattr(requests, method.lower()) if isinstance(data, dict): data = json.dumps(data) result = function(integration['uri'], data=data, headers=headers) return result else: msg = ('API Gateway integration type "%s" for method "%s" not yet implemented' % (integration['type'], method)) LOGGER.warning(msg) return make_error(msg, 404) return 200 if re.match(PATH_REGEX_AUTHORIZERS, path): return handle_authorizers(method, path, data, headers) return True
def forward_request(self, method, path, data, headers): data = data and json.loads(to_str(data)) # Paths to match regex2 = r'^/restapis/([A-Za-z0-9_\-]+)/([A-Za-z0-9_\-]+)/%s/(.*)$' % PATH_USER_REQUEST if re.match(regex2, path): search_match = re.search(regex2, path) api_id = search_match.group(1) relative_path = '/%s' % search_match.group(3) try: integration = aws_stack.get_apigateway_integration(api_id, method, path=relative_path) assert integration except Exception: # if we have no exact match, try to find an API resource that contains path parameters path_map = get_rest_api_paths(rest_api_id=api_id) try: extracted_path, resource = get_resource_for_path(path=relative_path, path_map=path_map) except Exception: return make_error('Unable to find path %s' % path, 404) integrations = resource.get('resourceMethods', {}) integration = integrations.get(method, {}) integration = integration.get('methodIntegration') if not integration: if method == 'OPTIONS' and 'Origin' in headers: # default to returning CORS headers if this is an OPTIONS request return get_cors_response(headers) return make_error('Unable to find integration for path %s' % path, 404) uri = integration.get('uri') if method == 'POST' and integration['type'] == 'AWS': if uri.endswith('kinesis:action/PutRecords'): template = integration['requestTemplates'][APPLICATION_JSON] new_request = aws_stack.render_velocity_template(template, data) # forward records to target kinesis stream headers = aws_stack.mock_aws_request_headers(service='kinesis') headers['X-Amz-Target'] = kinesis_listener.ACTION_PUT_RECORDS result = common.make_http_request(url=TEST_KINESIS_URL, method='POST', data=new_request, headers=headers) return result else: msg = 'API Gateway action uri "%s" not yet implemented' % uri LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'AWS_PROXY': if uri.startswith('arn:aws:apigateway:') and ':lambda:path' in uri: func_arn = uri.split(':lambda:path')[1].split('functions/')[1].split('/invocations')[0] data_str = json.dumps(data) if isinstance(data, dict) else data try: path_params = extract_path_params(path=relative_path, extracted_path=extracted_path) except Exception: path_params = {} result = lambda_api.process_apigateway_invocation(func_arn, relative_path, data_str, headers, path_params=path_params, method=method, resource_path=path) if isinstance(result, FlaskResponse): return flask_to_requests_response(result) response = Response() parsed_result = result if isinstance(result, dict) else json.loads(result) parsed_result = common.json_safe(parsed_result) response.status_code = int(parsed_result.get('statusCode', 200)) response.headers.update(parsed_result.get('headers', {})) try: if isinstance(parsed_result['body'], dict): response._content = json.dumps(parsed_result['body']) else: response._content = parsed_result['body'] except Exception: response._content = '{}' return response else: msg = 'API Gateway action uri "%s" not yet implemented' % uri LOGGER.warning(msg) return make_error(msg, 404) elif integration['type'] == 'HTTP': function = getattr(requests, method.lower()) if isinstance(data, dict): data = json.dumps(data) result = function(integration['uri'], data=data, headers=headers) return result else: msg = ('API Gateway integration type "%s" for method "%s" not yet implemented' % (integration['type'], method)) LOGGER.warning(msg) return make_error(msg, 404) return 200 if re.match(PATH_REGEX_AUTHORIZERS, path): return handle_authorizers(method, path, data, headers) return True