コード例 #1
0
    def handle_fn_getatt(self, intrinsic_value, ignore_errors):
        """
        { "Fn::GetAtt" : [ "logicalNameOfResource", "attributeName" ] }
        This intrinsic function gets the attribute for logical_resource specified. Each attribute might have a different
        functionality depending on the type.

        This intrinsic function will resolve all the objects within the function's value and check their type.
        This calls the symbol resolver in order to resolve the relevant attribute.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::GetAtt intrinsic function property

        Return
        -------
        A string with the resolved attributes
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value, ignore_errors, parent_function=IntrinsicResolver.FN_GET_ATT
        )
        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_GET_ATT)
        verify_number_arguments(arguments, IntrinsicResolver.FN_GET_ATT, num=2)

        logical_id = self.intrinsic_property_resolver(
            arguments[0], ignore_errors, parent_function=IntrinsicResolver.FN_GET_ATT
        )
        resource_type = self.intrinsic_property_resolver(
            arguments[1], ignore_errors, parent_function=IntrinsicResolver.FN_GET_ATT
        )

        verify_intrinsic_type_str(logical_id, IntrinsicResolver.FN_GET_ATT)
        verify_intrinsic_type_str(resource_type, IntrinsicResolver.FN_GET_ATT)

        return self._symbol_resolver.resolve_symbols(logical_id, resource_type)
コード例 #2
0
    def handle_fn_equals(self, intrinsic_value, ignore_errors):
        """
        {"Fn::Equals" : ["value_1", "value_2"]}
        This intrinsic function will verify that both items in the intrinsic function are equal after resolving them.

        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::Join intrinsic function property

        Return
        -------
        A boolean depending on if both arguments is equal
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value,
            ignore_errors,
            parent_function=IntrinsicResolver.FN_EQUALS)
        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_EQUALS)
        verify_number_arguments(arguments, IntrinsicResolver.FN_EQUALS, num=2)

        value_1 = self.intrinsic_property_resolver(
            arguments[0],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_EQUALS)
        value_2 = self.intrinsic_property_resolver(
            arguments[1],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_EQUALS)
        return value_1 == value_2
コード例 #3
0
    def handle_fn_split(self, intrinsic_value, ignore_errors):
        """
        { "Fn::Split" : [ "delimiter", "source string" ] }
        This function will then split the source_string based on the delimiter

        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
            This is the value of the object inside the Fn::Split intrinsic function property

        Return
        -------
        A string with the resolved attributes
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value, ignore_errors, parent_function=IntrinsicResolver.FN_SPLIT
        )

        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_SPLIT)

        delimiter = arguments[0]

        verify_intrinsic_type_str(delimiter, IntrinsicResolver.FN_SPLIT, position_in_list="first")

        source_string = self.intrinsic_property_resolver(
            arguments[1], ignore_errors, parent_function=IntrinsicResolver.FN_SPLIT
        )

        verify_intrinsic_type_str(source_string, IntrinsicResolver.FN_SPLIT, position_in_list="second")

        return source_string.split(delimiter)
コード例 #4
0
    def handle_fn_and(self, intrinsic_value):
        """
        {"Fn::And": [{condition}, {...}]}
        This intrinsic checks that every item in the list evaluates to a boolean. The items in the list can either
        be of the format {Condition: condition_name} which finds and evaluates the Conditions dictionary of another
        intrinsic function.

        The Conditions dictionary will have the following format:
        {
            "Conditions": {
                "condition_name": True/False or "{Intrinsic Function}"
            }
        }

        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::Join intrinsic function property

        Return
        -------
        A boolean depending on if all of the properties in Fn::And evaluate to True
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value, parent_function=IntrinsicResolver.FN_AND
        )
        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_AND)

        for i, argument in enumerate(arguments):
            if isinstance(argument, dict) and "Condition" in argument:
                condition_name = argument.get("Condition")
                verify_intrinsic_type_str(condition_name, IntrinsicResolver.FN_AND)

                condition = self._conditions.get(condition_name)
                verify_non_null(
                    condition,
                    IntrinsicResolver.FN_AND,
                    position_in_list=self.get_prefix_position_in_list(i),
                )

                condition_evaluated = self.intrinsic_property_resolver(
                    condition, parent_function=IntrinsicResolver.FN_AND
                )
                verify_intrinsic_type_bool(
                    condition_evaluated, IntrinsicResolver.FN_AND
                )

                if not condition_evaluated:
                    return False
            else:
                condition = self.intrinsic_property_resolver(
                    argument, parent_function=IntrinsicResolver.FN_AND
                )
                verify_intrinsic_type_bool(condition, IntrinsicResolver.FN_AND)

                if not condition:
                    return False

        return True
コード例 #5
0
    def handle_fn_if(self, intrinsic_value, ignore_errors):
        """
        {"Fn::If": [condition_name, value_if_true, value_if_false]}
        This intrinsic function will evaluate the condition from the Conditions dictionary and then return value_if_true
        or value_if_false depending on the value.

        The Conditions dictionary will have the following format:
        {
            "Conditions": {
                "condition_name": True/False or "{Intrinsic Function}"
            }
        }

        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::Join intrinsic function property

        Return
        -------
        This will return value_if_true and value_if_false depending on how the condition is evaluated
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value, ignore_errors, parent_function=IntrinsicResolver.FN_IF
        )
        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_IF)
        verify_number_arguments(arguments, IntrinsicResolver.FN_IF, num=3)

        condition_name = self.intrinsic_property_resolver(
            arguments[0], ignore_errors, parent_function=IntrinsicResolver.FN_IF
        )
        verify_intrinsic_type_str(condition_name, IntrinsicResolver.FN_IF)

        value_if_true = self.intrinsic_property_resolver(
            arguments[1], ignore_errors, parent_function=IntrinsicResolver.FN_IF
        )
        value_if_false = self.intrinsic_property_resolver(
            arguments[2], ignore_errors, parent_function=IntrinsicResolver.FN_IF
        )

        condition = self._conditions.get(condition_name)
        verify_intrinsic_type_dict(
            condition,
            IntrinsicResolver.FN_IF,
            message="The condition is missing in the Conditions dictionary for {}".format(IntrinsicResolver.FN_IF),
        )

        condition_evaluated = self.intrinsic_property_resolver(
            condition, ignore_errors, parent_function=IntrinsicResolver.FN_IF
        )
        verify_intrinsic_type_bool(
            condition_evaluated,
            IntrinsicResolver.FN_IF,
            message="The result of {} must evaluate to bool".format(IntrinsicResolver.FN_IF),
        )

        return value_if_true if condition_evaluated else value_if_false
コード例 #6
0
    def handle_fn_join(self, intrinsic_value, ignore_errors):
        """
        { "Fn::Join" : [ "delimiter", [ comma-delimited list of values ] ] }
        This function will join the items in the list together based on the string using the python join.

        This intrinsic function will resolve all the objects within the function's value and check their type.

        Parameter
        ----------
        intrinsic_value: list, dict
            This is the value of the object inside the Fn::Join intrinsic function property

        Return
        -------
        A string with the resolved attributes
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value,
            ignore_errors,
            parent_function=IntrinsicResolver.FN_JOIN)

        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_JOIN)

        delimiter = arguments[0]

        verify_intrinsic_type_str(delimiter,
                                  IntrinsicResolver.FN_JOIN,
                                  position_in_list="first")

        value_list = self.intrinsic_property_resolver(
            arguments[1],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_JOIN)

        verify_intrinsic_type_list(
            value_list,
            IntrinsicResolver.FN_JOIN,
            message="The list of values in {} after the "
            "delimiter must be a list".format(IntrinsicResolver.FN_JOIN),
        )

        sanitized_value_list = [
            self.intrinsic_property_resolver(
                item, ignore_errors, parent_function=IntrinsicResolver.FN_JOIN)
            for item in value_list
        ]
        verify_all_list_intrinsic_type(
            sanitized_value_list,
            verification_func=verify_intrinsic_type_str,
            property_type=IntrinsicResolver.FN_JOIN)

        return delimiter.join(sanitized_value_list)
コード例 #7
0
    def handle_fn_sub(self, intrinsic_value, ignore_errors):
        """
        { "Fn::Sub" : [ String, { Var1Name: Var1Value, Var2Name: Var2Value } ] } or { "Fn::Sub" : String }
        This intrinsic function will substitute the variables specified in the list into the string provided. The string
        will also parse out pseudo properties and anything of the form ${}.

        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::Join intrinsic function property

        Return
        -------
        A string with the resolved attributes
        """

        def resolve_sub_attribute(intrinsic_item, symbol_resolver):
            if "." in intrinsic_item:
                (logical_id, attribute_type) = intrinsic_item.rsplit(".", 1)
            else:
                (logical_id, attribute_type) = intrinsic_item, IntrinsicResolver.REF
            return symbol_resolver.resolve_symbols(logical_id, attribute_type, ignore_errors=True)

        if isinstance(intrinsic_value, str):
            intrinsic_value = [intrinsic_value, {}]

        verify_intrinsic_type_list(
            intrinsic_value, IntrinsicResolver.FN_SUB, message="The arguments to a Fn::Sub must be a list or a string"
        )

        verify_number_arguments(intrinsic_value, IntrinsicResolver.FN_SUB, num=2)

        sub_str = self.intrinsic_property_resolver(
            intrinsic_value[0], ignore_errors, parent_function=IntrinsicResolver.FN_SUB
        )
        verify_intrinsic_type_str(sub_str, IntrinsicResolver.FN_SUB, position_in_list="first")

        variables = intrinsic_value[1]
        verify_intrinsic_type_dict(variables, IntrinsicResolver.FN_SUB, position_in_list="second")

        sanitized_variables = self.intrinsic_property_resolver(
            variables, ignore_errors, parent_function=IntrinsicResolver.FN_SUB
        )

        subable_props = re.findall(string=sub_str, pattern=IntrinsicResolver._REGEX_SUB_FUNCTION)
        for sub_item in subable_props:
            sanitized_item = sanitized_variables[sub_item] if sub_item in sanitized_variables else sub_item
            result = resolve_sub_attribute(sanitized_item, self._symbol_resolver)
            sub_str = re.sub(pattern=r"\$\{" + sub_item + r"\}", string=sub_str, repl=str(result))
        return sub_str
コード例 #8
0
    def handle_fn_select(self, intrinsic_value, ignore_errors):
        """
        { "Fn::Select" : [ index, listOfObjects ] }
        It will select the item in the listOfObjects using python's base64.
        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::Select intrinsic function property

        Return
        -------
        A string with the resolved attributes
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value,
            ignore_errors,
            parent_function=IntrinsicResolver.FN_SELECT)

        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_SELECT)

        index = self.intrinsic_property_resolver(
            arguments[0],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_SELECT)

        verify_intrinsic_type_int(index, IntrinsicResolver.FN_SELECT)

        list_of_objects = self.intrinsic_property_resolver(
            arguments[1],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_SELECT)
        verify_intrinsic_type_list(list_of_objects,
                                   IntrinsicResolver.FN_SELECT)

        sanitized_objects = [
            self.intrinsic_property_resolver(
                item,
                ignore_errors,
                parent_function=IntrinsicResolver.FN_SELECT)
            for item in list_of_objects
        ]

        verify_in_bounds(index=index,
                         objects=sanitized_objects,
                         property_type=IntrinsicResolver.FN_SELECT)

        return sanitized_objects[index]
コード例 #9
0
    def handle_fn_not(self, intrinsic_value, ignore_errors):
        """
        {"Fn::Not": [{condition}]}
        This intrinsic function will negate the evaluation of the condition specified.

        This intrinsic function will resolve all the objects within the function's value and check their type.
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::Join intrinsic function property

        Return
        -------
        A boolean that is the opposite of the condition evaluated
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value,
            ignore_errors,
            parent_function=IntrinsicResolver.FN_NOT)
        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_NOT)
        verify_number_arguments(arguments, IntrinsicResolver.FN_NOT, num=1)
        argument_sanitised = self.intrinsic_property_resolver(
            arguments[0],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_NOT)
        if isinstance(argument_sanitised,
                      dict) and "Condition" in arguments[0]:
            condition_name = argument_sanitised.get("Condition")
            verify_intrinsic_type_str(condition_name, IntrinsicResolver.FN_NOT)

            condition = self._conditions.get(condition_name)
            verify_non_null(condition,
                            IntrinsicResolver.FN_NOT,
                            position_in_list="first")

            argument_sanitised = self.intrinsic_property_resolver(
                condition,
                ignore_errors,
                parent_function=IntrinsicResolver.FN_NOT)

        verify_intrinsic_type_bool(
            argument_sanitised,
            IntrinsicResolver.FN_NOT,
            message="The result of {} must evaluate to bool".format(
                IntrinsicResolver.FN_NOT),
        )
        return not argument_sanitised
コード例 #10
0
    def handle_find_in_map(self, intrinsic_value, ignore_errors):
        """
        { "Fn::FindInMap" : [ "MapName", "TopLevelKey", "SecondLevelKey"] } This function will then lookup the
        specified dictionary in the Mappings dictionary as mappings[map_name][top_level_key][second_level_key].

        This intrinsic function will resolve all the objects within the function's value and check their type.

        The format of the Mappings dictionary is:
        "Mappings": {
            "map_name": {
                "top_level_key": {
                    "second_level_key": "value"
                    }
                }
            }
        }
        Parameter
        ----------
        intrinsic_value: list, dict
           This is the value of the object inside the Fn::FindInMap intrinsic function property

        Return
        -------
        A string with the resolved attributes
        """
        arguments = self.intrinsic_property_resolver(
            intrinsic_value,
            ignore_errors,
            parent_function=IntrinsicResolver.FN_FIND_IN_MAP)

        verify_intrinsic_type_list(arguments, IntrinsicResolver.FN_FIND_IN_MAP)

        verify_number_arguments(arguments,
                                num=3,
                                property_type=IntrinsicResolver.FN_FIND_IN_MAP)

        map_name = self.intrinsic_property_resolver(
            arguments[0],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_FIND_IN_MAP)
        top_level_key = self.intrinsic_property_resolver(
            arguments[1],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_FIND_IN_MAP)
        second_level_key = self.intrinsic_property_resolver(
            arguments[2],
            ignore_errors,
            parent_function=IntrinsicResolver.FN_FIND_IN_MAP)

        verify_intrinsic_type_str(map_name,
                                  IntrinsicResolver.FN_FIND_IN_MAP,
                                  position_in_list="first")
        verify_intrinsic_type_str(top_level_key,
                                  IntrinsicResolver.FN_FIND_IN_MAP,
                                  position_in_list="second")
        verify_intrinsic_type_str(second_level_key,
                                  IntrinsicResolver.FN_FIND_IN_MAP,
                                  position_in_list="third")

        map_value = self._mapping.get(map_name)
        verify_intrinsic_type_dict(
            map_value,
            IntrinsicResolver.FN_FIND_IN_MAP,
            position_in_list="first",
            message=
            "The MapName is missing in the Mappings dictionary in Fn::FindInMap  for {}"
            .format(map_name),
        )

        top_level_value = map_value.get(top_level_key)
        verify_intrinsic_type_dict(
            top_level_value,
            IntrinsicResolver.FN_FIND_IN_MAP,
            message=
            "The TopLevelKey is missing in the Mappings dictionary in Fn::FindInMap "
            "for {}".format(top_level_key),
        )

        second_level_value = top_level_value.get(second_level_key)
        verify_intrinsic_type_str(
            second_level_value,
            IntrinsicResolver.FN_FIND_IN_MAP,
            message=
            "The SecondLevelKey is missing in the Mappings dictionary in Fn::FindInMap  "
            "for {}".format(second_level_key),
        )

        return second_level_value