def to_py27_compatible_template()

in samtranslator/utils/py27hash_fix.py [0:0]


def to_py27_compatible_template(template, parameter_values=None):
    """
    Convert an input template to a py27hash-compatible template. This function has to be run before any
    manipulation occurs for sake of keeping the same initial state. This function modifies the input template,
    rather than return a copied template. We choose not to return a copy because copying the template might
    change its internal state in Py2.7.
    We only convert necessary parts in the template which could affect the hash generation for Serverless Api
    template is modified
    Also update parameter_values to py27hash-compatible if it is provided.

    Parameters
    ----------
    template: dict
        input template

    Returns
    -------
    None
    """
    # Passing to parser for a simple validation. Validation is normally done within translator.translate(...).
    # However, becuase this conversion is done before translate and also requires the template to be valid, we
    # perform a simple validation here to just make sure the template is minimally safe for conversion.
    Parser.validate_datatypes(template)

    if not _template_has_api_resource(template) and not _template_has_httpapi_resource_with_default_authorizer(
        template
    ):
        # no need to convert when all of the following conditions are true:
        # 1. template does not contain any API resource
        # 2. template does not contain any HttpApi resource with DefaultAuthorizer (TODO: remove after py3 migration and fix of security issue)
        return

    if "Globals" in template and isinstance(template["Globals"], dict) and "Api" in template["Globals"]:
        # "Api" section under "Globals" could affect swagger generation for AWS::Serverless::Api resources
        template["Globals"]["Api"] = _convert_to_py27_type(template["Globals"]["Api"])

    if "Parameters" in template and isinstance(template["Parameters"], dict):
        new_parameters_dict = Py27Dict()
        for logical_id, param_dict in template["Parameters"].items():
            if isinstance(param_dict, dict) and "Default" in param_dict:
                param_dict["Default"] = _convert_to_py27_type(param_dict["Default"])

            # dict keys have to be Py27UniStr for correct serialization
            new_parameters_dict[Py27UniStr(logical_id)] = param_dict
        template["Parameters"] = new_parameters_dict

    if "Resources" in template and isinstance(template["Resources"], dict):
        new_resources_dict = Py27Dict()
        for logical_id, resource_dict in template["Resources"].items():
            if isinstance(resource_dict, dict):
                resource_type = resource_dict.get("Type")
                resource_properties = resource_dict.get("Properties")
                if resource_properties is not None:
                    # We only convert for AWS::Serverless::Api resource
                    if resource_type in [
                        "AWS::Serverless::Api",
                        "AWS::Serverless::HttpApi",
                    ]:
                        resource_dict["Properties"] = _convert_to_py27_type(resource_properties)
                    elif resource_type in ["AWS::Serverless::Function", "AWS::Serverless::StateMachine"]:
                        # properties below could affect swagger generation
                        if "Condition" in resource_dict:
                            resource_dict["Condition"] = _convert_to_py27_type(resource_dict["Condition"])
                        if "FunctionName" in resource_properties:
                            resource_properties["FunctionName"] = _convert_to_py27_type(
                                resource_properties["FunctionName"]
                            )
                        if "Events" in resource_properties:
                            resource_properties["Events"] = _convert_to_py27_type(resource_properties["Events"])

            new_resources_dict[Py27UniStr(logical_id)] = resource_dict
        template["Resources"] = new_resources_dict

    if parameter_values:
        for key, val in parameter_values.items():
            parameter_values[key] = _convert_to_py27_type(val)