示例#1
0
    def __enter__(self):
        self._template_dict = get_template_data(self._template_file)

        self._function_provider = SamFunctionProvider(
            self._template_dict, self._parameter_overrides)
        self._layer_provider = SamLayerProvider(self._template_dict,
                                                self._parameter_overrides)

        if not self._base_dir:
            # Base directory, if not provided, is the directory containing the template
            self._base_dir = str(
                pathlib.Path(self._template_file).resolve().parent)

        self._build_dir = self._setup_build_dir(self._build_dir, self._clean)

        if self._cached:
            cache_path = pathlib.Path(self._cache_dir)
            cache_path.mkdir(mode=self._BUILD_DIR_PERMISSIONS,
                             parents=True,
                             exist_ok=True)
            self._cache_dir = str(cache_path.resolve())

        if self._use_container:
            self._container_manager = ContainerManager(
                docker_network_id=self._docker_network,
                skip_pull_image=self._skip_pull_image)

        return self
    def test_must_return_function_value(self):
        provider = SamFunctionProvider({})
        provider.functions = {
            "func1": "value"
        }  # Cheat a bit here by setting the value of this property directly

        self.assertEqual("value", provider.get("func1"))
示例#3
0
    def __enter__(self):
        """
        Performs some basic checks and returns itself when everything is ready to invoke a Lambda function.

        :returns InvokeContext: Returns this object
        """

        # Grab template from file and create a provider
        self._template_dict = self._get_template_data(self._template_file)
        self._function_provider = SamFunctionProvider(self._template_dict,
                                                      self.parameter_overrides)

        self._env_vars_value = self._get_env_vars_value(self._env_vars_file)
        self._log_file_handle = self._setup_log_file(self._log_file)

        self._debug_context = self._get_debug_context(self._debug_ports,
                                                      self._debug_args,
                                                      self._debugger_path)

        self._container_manager = self._get_container_manager(
            self._docker_network, self._skip_pull_image)

        if not self._container_manager.is_docker_reachable:
            raise InvokeContextException(
                "Running AWS SAM projects locally requires Docker. Have you got it installed?"
            )

        return self
示例#4
0
    def test_must_return_function_value(self):
        provider = SamFunctionProvider([])
        # Cheat a bit here by setting the value of this property directly
        function = Function(
            name="not-value",
            functionname="value",
            runtime=None,
            handler=None,
            codeuri=None,
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[],
            events=None,
            metadata=None,
            inlinecode=None,
            imageuri=None,
            imageconfig=None,
            packagetype=None,
            codesign_config_arn=None,
            stack_path=STACK_PATH,
        )
        provider.functions = {"func1": function}

        self.assertEqual(function, provider.get("value"))
示例#5
0
def auth_per_resource(stacks: List[Stack]):
    """
    Check if authentication has been set for the function resources defined in the template that have `Api` Event type.

    Parameters
    ----------
    stacks: List[Stack]
        The list of stacks where resources are looked for

    Returns
    -------

    List of tuples per function resource that have the `Api` or `HttpApi` event types, that describes the resource name
    and if authorization is required per resource.

    """

    _auth_per_resource: List[Tuple[str, bool]] = []

    sam_function_provider = SamFunctionProvider(
        stacks, ignore_code_extraction_warnings=True)
    for sam_function in sam_function_provider.get_all():
        # Only check for auth if there are function events defined.
        if sam_function.events:
            _auth_resource_event(sam_function_provider, sam_function,
                                 _auth_per_resource)

    return _auth_per_resource
示例#6
0
def auth_per_resource(parameter_overrides, template_dict):
    """
    Check if authentication has been set for the function resources defined in the template that have `Api` Event type.

    Parameters
    ----------
    parameter_overrides: dict
        list of parameter overrides for the parameters defined in the template
    template_dict: dict
        Raw dictionary of the defined SAM template

    Returns
    -------

    List of tuples per function resource that have the `Api` or `HttpApi` event types, that describes the resource name
    and if authorization is required per resource.

    """

    _auth_per_resource = []

    sam_functions = SamFunctionProvider(
        template_dict=template_dict,
        parameter_overrides=parameter_overrides,
        ignore_code_extraction_warnings=True)
    for sam_function in sam_functions.get_all():
        # Only check for auth if there are function events defined.
        if sam_function.events:
            _auth_resource_event(sam_functions, sam_function,
                                 _auth_per_resource)

    return _auth_per_resource
 def setUp(self):
     self.parameter_overrides = {}
     root_stack = Stack("", "", "template.yaml", self.parameter_overrides, self.TEMPLATE)
     child_stack = Stack("", "ChildStack", "./child/template.yaml", None, self.CHILD_TEMPLATE)
     with patch("samcli.lib.providers.sam_stack_provider.get_template_data") as get_template_data_mock:
         get_template_data_mock.side_effect = lambda t: {
             "template.yaml": self.TEMPLATE,
             "./child/template.yaml": self.CHILD_TEMPLATE,
         }
         self.provider = SamFunctionProvider([root_stack, child_stack])
示例#8
0
    def __enter__(self):
        """
        Performs some basic checks and returns itself when everything is ready to invoke a Lambda function.

        :returns InvokeContext: Returns this object
        """

        # Grab template from file and create a provider
        self._template_dict = self._get_template_data(self._template_file)
        self._function_provider = SamFunctionProvider(self._template_dict,
                                                      self.parameter_overrides)

        self._env_vars_value = self._get_env_vars_value(self._env_vars_file)
        self._container_env_vars_value = self._get_env_vars_value(
            self._container_env_vars_file)
        self._log_file_handle = self._setup_log_file(self._log_file)

        # in case of warm containers && debugging is enabled && if debug-function property is not provided, so
        # if the provided template only contains one lambda function, so debug-function will be set to this function
        # if the template contains multiple functions, a warning message "that the debugging option will be ignored"
        # will be printed
        if self._containers_mode == ContainersMode.WARM and self._debug_ports and not self._debug_function:
            if len(self._function_provider.functions) == 1:
                self._debug_function = list(
                    self._function_provider.functions.keys())[0]
            else:
                LOG.info(
                    "Warning: you supplied debugging options but you did not specify the --debug-function option."
                    " To specify which function you want to debug, please use the --debug-function <function-name>"
                )
                # skipp the debugging
                self._debug_ports = None

        self._debug_context = self._get_debug_context(
            self._debug_ports,
            self._debug_args,
            self._debugger_path,
            self._container_env_vars_value,
            self._debug_function,
        )

        self._container_manager = self._get_container_manager(
            self._docker_network, self._skip_pull_image, self._shutdown)

        if not self._container_manager.is_docker_reachable:
            raise InvokeContextException(
                "Running AWS SAM projects locally requires Docker. Have you got it installed and running?"
            )

        # initialize all lambda function containers upfront
        if self._containers_initializing_mode == ContainersInitializationMode.EAGER:
            self._initialize_all_functions_containers()

        return self
示例#9
0
    def test_must_handle_code_s3_uri(self):

        name = "myname"
        properties = {"CodeUri": "s3://bucket/key"}

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEqual(result.codeuri, ".")  # Default value
    def test_must_use_inlinecode(self):

        name = "myname"
        properties = {
            "InlineCode": "testcode",
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "30",
            "Handler": "index.handler",
        }

        expected = Function(
            name="myname",
            functionname="myname",
            runtime="myruntime",
            memory="mymemorysize",
            timeout="30",
            handler="index.handler",
            codeuri=None,
            environment=None,
            rolearn=None,
            layers=[],
            events=None,
            metadata=None,
            inlinecode="testcode",
            imageuri=None,
            imageconfig=None,
            packagetype=ZIP,
            codesign_config_arn=None,
            stack_path=STACK_PATH,
        )

        result = SamFunctionProvider._convert_sam_function_resource(STACK, name, properties, [])

        self.assertEqual(expected, result)
    def test_must_work_for_multiple_functions_with_name_but_in_different_stacks(
        self,
        convert_mock,
    ):
        function_root = Mock()
        function_root.name = "Func1"
        function_root.full_path = "Func1"
        function_child = Mock()
        function_child.name = "Func1"
        function_child.full_path = "C/Func1"

        stack_root = Mock()
        stack_root.resources = {
            "Func1": {"Type": "AWS::Lambda::Function", "Properties": {"a": "b"}},
            "C": {"Type": "AWS::Serverless::Application", "Properties": {"Location": "./child.yaml"}},
        }
        stack_child = Mock()
        stack_child.resources = {
            "Func1": {"Type": "AWS::Lambda::Function", "Properties": {"a": "b"}},
        }

        convert_mock.side_effect = [function_root, function_child]

        expected = {"Func1": function_root, "C/Func1": function_child}

        result = SamFunctionProvider._extract_functions([stack_root, stack_child])
        self.assertEqual(expected, result)
        convert_mock.assert_has_calls(
            [
                call(stack_root, "Func1", {"a": "b"}, [], False),
                call(stack_child, "Func1", {"a": "b"}, [], False),
            ]
        )
    def test_must_skip_unknown_resource(self, resources_mock):
        resources_mock.return_value = {"Func1": {"Type": "AWS::SomeOther::Function", "Properties": {"a": "b"}}}

        expected = {}

        result = SamFunctionProvider._extract_functions([make_root_stack(None)])
        self.assertEqual(expected, result)
示例#13
0
    def test_must_skip_non_existent_properties(self):

        name = "myname"
        properties = {"Code": {"Bucket": "bucket"}}

        expected = Function(
            name="myname",
            functionname="myname",
            runtime=None,
            memory=None,
            timeout=None,
            handler=None,
            codeuri=".",
            environment=None,
            rolearn=None,
            layers=[],
            events=None,
            metadata=None,
            codesign_config_arn=None,
        )

        result = SamFunctionProvider._convert_lambda_function_resource(
            name, properties, [])

        self.assertEqual(expected, result)
    def test_layers_created_from_template_resources(self):
        resources = {
            "Layer": {"Type": "AWS::Lambda::LayerVersion", "Properties": {"Content": {"Bucket": "bucket"}}},
            "ServerlessLayer": {"Type": "AWS::Serverless::LayerVersion", "Properties": {"ContentUri": "/somepath"}},
        }

        list_of_layers = [
            {"Ref": "Layer"},
            {"Ref": "ServerlessLayer"},
            "arn:aws:lambda:region:account-id:layer:layer-name:1",
            {"NonRef": "Something"},
        ]
        actual = SamFunctionProvider._parse_layer_info(
            Mock(stack_path=STACK_PATH, location="template.yaml", resources=resources), list_of_layers
        )

        for (actual_layer, expected_layer) in zip(
            actual,
            [
                LayerVersion("Layer", ".", stack_path=STACK_PATH),
                LayerVersion("ServerlessLayer", "/somepath", stack_path=STACK_PATH),
                LayerVersion("arn:aws:lambda:region:account-id:layer:layer-name:1", None, stack_path=STACK_PATH),
            ],
        ):
            self.assertEqual(actual_layer, expected_layer)
示例#15
0
    def test_must_convert(self):

        name = "myname"
        properties = {
            "CodeUri": "/usr/local",
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "30",
            "Handler": "myhandler",
            "Environment": "myenvironment",
            "Role": "myrole",
            "Layers": ["Layer1", "Layer2"],
        }

        expected = Function(
            name="myname",
            functionname="myname",
            runtime="myruntime",
            memory="mymemorysize",
            timeout="30",
            handler="myhandler",
            codeuri="/usr/local",
            environment="myenvironment",
            rolearn="myrole",
            layers=["Layer1", "Layer2"],
            events=None,
            metadata=None,
            codesign_config_arn=None,
        )

        result = SamFunctionProvider._convert_sam_function_resource(
            name, properties, ["Layer1", "Layer2"])

        self.assertEqual(expected, result)
    def test_must_skip_non_existent_properties(self):

        name = "myname"
        properties = {"CodeUri": "/usr/local"}

        expected = Function(
            name="myname",
            functionname="myname",
            runtime=None,
            memory=None,
            timeout=None,
            handler=None,
            codeuri="/usr/local",
            environment=None,
            rolearn=None,
            layers=[],
            events=None,
            metadata=None,
            imageuri=None,
            imageconfig=None,
            packagetype=ZIP,
            codesign_config_arn=None,
        )

        result = SamFunctionProvider._convert_sam_function_resource(
            name, properties, [])

        self.assertEqual(expected, result)
示例#17
0
    def test_must_default_missing_code_uri(self):

        name = "myname"
        properties = {"Runtime": "myruntime"}

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEqual(result.codeuri, ".")  # Default value
示例#18
0
    def test_must_convert(self):

        name = "myname"
        properties = {
            "Code": {
                "Bucket": "bucket"
            },
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "30",
            "Handler": "myhandler",
            "Environment": "myenvironment",
            "Role": "myrole",
            "Layers": ["Layer1", "Layer2"],
        }

        expected = Function(
            name="myname",
            functionname="myname",
            runtime="myruntime",
            memory="mymemorysize",
            timeout="30",
            handler="myhandler",
            codeuri=".",
            environment="myenvironment",
            rolearn="myrole",
            layers=["Layer1", "Layer2"],
            events=None,
        )

        result = SamFunctionProvider._convert_lambda_function_resource(
            name, properties, ["Layer1", "Layer2"])

        self.assertEqual(expected, result)
示例#19
0
    def test_must_skip_unknown_resource(self):
        resources = {"Func1": {"Type": "AWS::SomeOther::Function", "Properties": {"a": "b"}}}

        expected = {}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEqual(expected, result)
    def test_return_empty_list_on_no_layers(self):
        resources = {"Function": {"Type": "AWS::Serverless::Function", "Properties": {}}}

        actual = SamFunctionProvider._parse_layer_info(
            Mock(stack_path=STACK_PATH, location="template.yaml", resources=resources), []
        )

        self.assertEqual(actual, [])
示例#21
0
    def test_must_return_function_value(self):
        provider = SamFunctionProvider({})
        # Cheat a bit here by setting the value of this property directly
        function = Function(
            name="not-value",
            functionname="value",
            runtime=None,
            handler=None,
            codeuri=None,
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[],
        )
        provider.functions = {"func1": function}

        self.assertEqual(function, provider.get("value"))
示例#22
0
    def __enter__(self):
        self._template_dict = get_template_data(self._template_file)

        self._function_provider = SamFunctionProvider(
            self._template_dict, self._parameter_overrides)

        if not self._base_dir:
            # Base directory, if not provided, is the directory containing the template
            self._base_dir = str(
                pathlib.Path(self._template_file).resolve().parent)

        self._build_dir = self._setup_build_dir(self._build_dir, self._clean)

        if self._use_container:
            self._container_manager = ContainerManager(
                docker_network_id=self._docker_network,
                skip_pull_image=self._skip_pull_image)

        return self
示例#23
0
    def test_must_default_to_empty_resources(self, extract_mock, get_template_mock):
        extract_result = {"foo": "bar"}
        extract_mock.return_value = extract_result

        template = {"a": "b"}  # Template does *not* have 'Resources' key
        get_template_mock.return_value = template
        provider = SamFunctionProvider(template, parameter_overrides=self.parameter_overrides)

        extract_mock.assert_called_with({}, False)  # Empty Resources value must be passed
        self.assertEqual(provider.functions, extract_result)
        self.assertEqual(provider.resources, {})
示例#24
0
    def test_must_extract_functions(self, extract_mock, get_template_mock):
        extract_result = {"foo": "bar"}
        extract_mock.return_value = extract_result

        template = {"Resources": {"a": "b"}}
        get_template_mock.return_value = template
        provider = SamFunctionProvider(template, parameter_overrides=self.parameter_overrides)

        extract_mock.assert_called_with({"a": "b"}, False)
        get_template_mock.assert_called_with(template, self.parameter_overrides)
        self.assertEqual(provider.functions, extract_result)
示例#25
0
    def test_must_work_for_lambda_function(self, convert_mock):
        convertion_result = "some result"
        convert_mock.return_value = convertion_result

        resources = {"Func1": {"Type": "AWS::Lambda::Function", "Properties": {"a": "b"}}}

        expected = {"Func1": "some result"}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEqual(expected, result)
        convert_mock.assert_called_with("Func1", {"a": "b"}, [])
示例#26
0
    def test_return_empty_list_on_no_layers(self):
        resources = {
            "Function": {
                "Type": "AWS::Serverless::Function",
                "Properties": {}
            }
        }

        actual = SamFunctionProvider._parse_layer_info([], resources)

        self.assertEqual(actual, [])
示例#27
0
    def test_must_work_for_sam_function(self, convert_mock):
        convertion_result = "some result"
        convert_mock.return_value = convertion_result

        resources = {"Func1": {"Type": "AWS::Serverless::Function", "Properties": {"a": "b"}}}

        expected = {"Func1": "some result"}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEqual(expected, result)
        convert_mock.assert_called_with("Func1", {"a": "b"}, [], ignore_code_extraction_warnings=False)
示例#28
0
    def test_must_handle_code_dict(self):

        name = "myname"
        properties = {
            "CodeUri": {
                # CodeUri is some dictionary
                "a": "b"
            }
        }

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEqual(result.codeuri, ".")  # Default value
    def test_must_work_for_sam_function(self, convert_mock, resources_mock):
        convertion_result = Mock()
        convertion_result.full_path = "A/B/C/Func1"
        convert_mock.return_value = convertion_result

        resources_mock.return_value = {"Func1": {"Type": "AWS::Serverless::Function", "Properties": {"a": "b"}}}
        expected = {"A/B/C/Func1": convertion_result}

        stack = make_root_stack(None)
        result = SamFunctionProvider._extract_functions([stack])
        self.assertEqual(expected, result)
        convert_mock.assert_called_with(stack, "Func1", {"a": "b"}, [], False, ignore_code_extraction_warnings=False)
示例#30
0
def transform_template(parameter_overrides, template_dict):
    """

    :param parameter_overrides: Dictionary of parameter overrides for the SAM template.
    :param template_dict: Dictionary representation of the SAM template.
    :return:
    """
    sam_functions = SamFunctionProvider(
        template_dict=template_dict, parameter_overrides=parameter_overrides, ignore_code_extraction_warnings=True
    )

    return sam_functions