Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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))