def __initialize_jinja(context): third_party_json_path = os.path.join(context.config.root_directory_path, "BinTemp", "3rdParty.json") if not os.path.isfile(third_party_json_path): raise HandledError( "The file 3rdParty.json was not found at {}. You must run lmbr_waf configure before you can generate service API code." .format(os.path.dirname(third_party_json_path))) with open(third_party_json_path, "r") as fp: third_party_json = json.load(fp) third_party_root = third_party_json['3rdPartyRoot'] sdks = third_party_json['SDKs'] sdk_paths = {} for sdk_name in ('jinja2', 'markupsafe'): sdk_info = sdks.get(sdk_name, None) if not sdk_info: raise HandledError( 'The {} Python library was not found at {}. You must select the "Compile the game code" option in SetupAssistant before you can generate service API code.' .format(sdk_name, third_party_root)) sdk_path = os.path.join(third_party_root, sdk_info['base_source'], 'x64') sdk_paths[sdk_name] = sdk_path sys.path.append(sdk_path) jinja_path = os.path.join(sdk_paths['jinja2'], 'jinja2') loaders_module = module_utils.load_module('loaders', jinja_path) template_path = os.path.join(os.path.dirname(__file__), 'templates') print 'template_path', template_path loader = loaders_module.FileSystemLoader(template_path) environment_module = module_utils.load_module('environment', jinja_path) environment = environment_module.Environment(loader=loader) return environment
def __initialize_jinja(context): jinja_path = os.path.join(context.config.root_directory_path, 'Code', 'SDKs', 'jinja2', 'x64') if not os.path.isdir(jinja_path): raise HandledError('The jinja2 Python library was not found at {}. You must select the "Compile the game code" option in SetupAssistant before you can generate service API code.'.format(jinja_path)) sys.path.append(jinja_path) markupsafe_path = os.path.join(context.config.root_directory_path, 'Code', 'SDKs', 'markupsafe', 'x64') if not os.path.isdir(markupsafe_path): raise HandledError('The markupsafe Python library was not found at {}. You must select the "Complile the game code" option in SetupAssistant before you can generate service API code.'.format(markupsafe_path)) sys.path.append(markupsafe_path) loaders_module = module_utils.load_module('loaders', os.path.join(jinja_path, 'jinja2')) template_path = os.path.join(os.path.dirname(__file__), 'templates') print 'template_path', template_path loader = loaders_module.FileSystemLoader(template_path) environment_module = module_utils.load_module('environment', os.path.join(jinja_path, 'jinja2')) environment = environment_module.Environment(loader=loader) return environment
def handler(event, context): """Main handler for custom resources, wired in via project-template.json as the ProjectResourceHandler""" try: print('Dispatching event {} with context {}.'.format( json.dumps(event, cls=json_utils.SafeEncoder), context)) resource_type = event.get('ResourceType', None) if resource_type is None: raise RuntimeError('No ResourceType specified.') if resource_type in _LOCAL_CUSTOM_RESOURCE_WHITELIST: # Old method for supporting custom resource code directly within the ProjectResourceHandler. # Should only be used for legacy types in the ProjectResourceHandler. module_name = resource_type.replace('Custom::', '') + 'ResourceHandler' module = sys.modules.get(module_name, None) if module is None: # First check for handler module in same directory as this module, # if not found, check for module in the resource group provided # directories. module_file_name = module_name + '.py' module_file_path = os.path.join(os.path.dirname(__file__), module_file_name) if os.path.isfile(module_file_path): module = module_utils.load_module( module_name, os.path.dirname(module_file_path)) elif os.path.isdir(PLUGIN_DIRECTORY_PATH): plugin_directory_names = [ item for item in os.listdir(PLUGIN_DIRECTORY_PATH) if os.path.isdir( os.path.join(PLUGIN_DIRECTORY_PATH, item)) ] for plugin_directory_name in plugin_directory_names: module_file_path = os.path.join( PLUGIN_DIRECTORY_PATH, plugin_directory_name, module_file_name) if os.path.isfile(module_file_path): module = module_utils.load_module( module_name, os.path.dirname(module_file_path)) break if module is not None: if not hasattr(module, 'handler'): raise RuntimeError( 'No handler function found for the {} resource type.'. format(resource_type)) print('Using {}'.format(module)) module.handler(event, context) else: # New way of instantiating custom resources. Load the dictionary of resource types. stack = stack_info.StackInfoManager().get_stack_info( event['StackId']) type_definition = stack.resource_definitions.get( resource_type, None) if type_definition is None: raise RuntimeError( 'No type definition found for the {} resource type.'. format(resource_type)) if type_definition.handler_function is None: raise RuntimeError( 'No handler function defined for custom resource type {}.'. format(resource_type)) request_type = event['RequestType'] if type_definition.deleted and request_type == "Create": raise RuntimeError( 'Attempting to Create a new resource of deleted type {}.'. format(resource_type)) create_version = type_definition.handler_function_version logical_id = event['LogicalResourceId'] embedded_physical_id = None # Access control can take over 60s so set custom timeouts config_dict = { 'region_name': stack.region, 'connect_timeout': LAMBDA_CONNECTION_TIMEOUT, 'read_timeout': LAMBDA_READ_TIMEOUT } lambda_client_config = Config(**config_dict) lambda_client = aws_utils.ClientWrapper( boto3.client("lambda", config=lambda_client_config)) cf_client = aws_utils.ClientWrapper( boto3.client("cloudformation", stack.region)) if request_type != "Create": physical_id = event['PhysicalResourceId'] embedded_physical_id = physical_id try: existing_resource_info = json.loads(physical_id) embedded_physical_id = existing_resource_info['id'] create_version = existing_resource_info['v'] except (ValueError, TypeError, KeyError): # Backwards compatibility with resources created prior to versioning support create_version = None run_version = create_version # Check the metadata on the resource to see if we're coercing to a different version resource_info = cf_client.describe_stack_resource( StackName=event['StackId'], LogicalResourceId=logical_id) metadata = aws_utils.get_cloud_canvas_metadata( resource_info['StackResourceDetail'], custom_resource_utils.METADATA_VERSION_TAG) if metadata: run_version = metadata if request_type == "Create": create_version = metadata # Configure our invocation, and invoke the handler lambda lambda_data = {'Handler': type_definition.handler_function} lambda_data.update(event) invoke_params = { 'FunctionName': type_definition.get_custom_resource_lambda_function_name(), 'Payload': json.dumps(lambda_data) } if run_version: invoke_params['Qualifier'] = run_version response = lambda_client.invoke(**invoke_params) if response['StatusCode'] == 200: response_data = json.loads(response['Payload'].read().decode()) response_success = response_data.get('Success', None) if response_success is not None: if response_success: if create_version: if request_type == "Update" and response_data[ 'PhysicalResourceId'] != embedded_physical_id: # Physical ID changed during an update, which is *technically* illegal according to the # docs, but we allow it because CloudFormation doesn't act to prevent it. print( _UPDATE_CHANGED_PHYSICAL_ID_WARNING.format( logical_id, embedded_physical_id, response_data['PhysicalResourceId'])) out_resource_id = json.dumps({ 'id': response_data['PhysicalResourceId'], 'v': create_version }) else: # Backwards compatibility with resources created prior to versioning support out_resource_id = response_data[ 'PhysicalResourceId'] custom_resource_response.succeed( event, context, response_data['Data'], out_resource_id) else: custom_resource_response.fail(event, context, response_data['Reason']) else: raise RuntimeError( "Handler lambda for resource type '%s' returned a malformed response: %s" % (resource_type, response_data)) else: raise RuntimeError( "Handler lambda for resource type '%s' failed to execute, returned HTTP status %d" % (resource_type, response['StatusCode'])) except ValidationError as e: custom_resource_response.fail(event, context, str(e)) except Exception as e: print( 'Unexpected error occurred when processing event {} with context {}. {}' .format(event, context, traceback.format_exc())) custom_resource_response.fail( event, context, 'Unexpected {} error occurred: {}. Additional details can be found in the CloudWatch log group {} stream {}' .format( type(e).__name__, str(e), context.log_group_name, context.log_stream_name))
def handler(event, context): try: print 'Dispatching event {} with context {}.'.format( json.dumps(event, cls=json_utils.SafeEncoder), context) resource_type = event.get('ResourceType', None) if resource_type is None: raise RuntimeError('No ResourceType specified.') if resource_type in _LOCAL_CUSTOM_RESOURCE_WHITELIST: # Old method for supporting custom resource code directly within the ProjectResourceHandler. # Should only be used for legacy types in the ProjectResourceHandler. module_name = resource_type.replace('Custom::', '') + 'ResourceHandler' module = sys.modules.get(module_name, None) if module is None: # First check for handler module in same directory as this module, # if not found, check for module in the resource group provided # directories. module_file_name = module_name + '.py' module_file_path = os.path.join(os.path.dirname(__file__), module_file_name) if os.path.isfile(module_file_path): module = module_utils.load_module( module_name, os.path.dirname(module_file_path)) elif os.path.isdir(PLUGIN_DIRECTORY_PATH): plugin_directory_names = [ item for item in os.listdir(PLUGIN_DIRECTORY_PATH) if os.path.isdir( os.path.join(PLUGIN_DIRECTORY_PATH, item)) ] for plugin_directory_name in plugin_directory_names: module_file_path = os.path.join( PLUGIN_DIRECTORY_PATH, plugin_directory_name, module_file_name) if os.path.isfile(module_file_path): module = module_utils.load_module( module_name, os.path.dirname(module_file_path)) break if module is not None: if not hasattr(module, 'handler'): raise RuntimeError( 'No handler function found for the {} resource type.'. format(resource_type)) print 'Using {}'.format(module) module.handler(event, context) else: # New way of instantiating custom resources. Load the dictionary of resource types. stack = stack_info.StackInfoManager().get_stack_info( event['StackId']) type_definition = stack.resource_definitions.get( resource_type, None) if type_definition is None: raise RuntimeError( 'No type definition found for the {} resource type.'. format(resource_type)) if type_definition.handler_function is None: raise RuntimeError( 'No handler function defined for custom resource type {}.'. format(resource_type)) lambda_client = aws_utils.ClientWrapper( boto3.client("lambda", stack.region)) lambda_data = {'Handler': type_definition.handler_function} lambda_data.update(event) response = lambda_client.invoke( FunctionName=type_definition. get_custom_resource_lambda_function_name(), Payload=json.dumps(lambda_data)) if response['StatusCode'] == 200: response_data = json.loads(response['Payload'].read().decode()) response_success = response_data.get('Success', None) if response_success is not None: if response_success: custom_resource_response.succeed( event, context, response_data['Data'], response_data['PhysicalResourceId']) else: custom_resource_response.fail(event, context, response_data['Reason']) else: raise RuntimeError( "Handler lambda for resource type '%s' returned a malformed response: %s" % (resource_type, response_data)) else: raise RuntimeError( "Handler lambda for resource type '%s' failed to execute, returned HTTP status %d" % (resource_type, response['StatusCode'])) except ValidationError as e: custom_resource_response.fail(event, context, str(e)) except Exception as e: print 'Unexpected error occured when processing event {} with context {}. {}'.format( event, context, traceback.format_exc()) custom_resource_response.fail( event, context, 'Unexpected {} error occured: {}. Additional details can be found in the CloudWatch log group {} stream {}' .format( type(e).__name__, e.message, context.log_group_name, context.log_stream_name))