def test_disable_python(self, mock_gen_aws_client,
                            mock_get_serialized_lambda_function):
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client

        mock_client.get_function = MagicMock(
            return_value={
                "Configuration": {
                    "FunctionName":
                    "lambdaF",
                    "Runtime":
                    "python3.6",
                    "FunctionArn":
                    "arn:aws:lambda:us-east-2:599817902985:function:lambdaF",
                    "Handler":
                    "sentry_sdk.integrations.init_serverless_sdk.sentry_lambda_handler",
                    "Layers": [
                        {
                            "Arn":
                            "arn:aws:lambda:us-east-2:1234:layer:something-else:2"
                        },
                        {
                            "Arn":
                            "arn:aws:lambda:us-east-2:1234:layer:my-python-layer:34"
                        },
                    ],
                    "Environment": {
                        "Variables": {
                            "SENTRY_INITIAL_HANDLER":
                            "lambda_handler.test_handler",
                            "SENTRY_DSN": self.sentry_dsn,
                            "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                            "OTHER": "hi",
                        }
                    },
                },
            })
        mock_client.update_function_configuration = MagicMock()
        return_value = {
            "name": "lambdaF",
            "runtime": "python3.6",
            "version": -1,
            "outOfDate": False,
            "enabled": False,
        }
        mock_get_serialized_lambda_function.return_value = return_value

        assert self.get_response(action="disable",
                                 target="lambdaF").data == return_value

        mock_client.get_function.assert_called_with(FunctionName="lambdaF")

        mock_client.update_function_configuration.assert_called_with(
            FunctionName="lambdaF",
            Layers=["arn:aws:lambda:us-east-2:1234:layer:something-else:2"],
            Environment={"Variables": {
                "OTHER": "hi"
            }},
            Handler="lambda_handler.test_handler",
        )
예제 #2
0
    def test_update_version(self, mock_gen_aws_client,
                            mock_get_serialized_lambda_function):
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client

        mock_client.get_function = MagicMock(
            return_value={
                "Configuration": {
                    "FunctionName":
                    "lambdaD",
                    "Runtime":
                    "nodejs10.x",
                    "FunctionArn":
                    "arn:aws:lambda:us-east-2:599817902985:function:lambdaD",
                    "Layers": [
                        {
                            "Arn":
                            "arn:aws:lambda:us-east-2:1234:layer:something-else:2"
                        },
                        {
                            "Arn":
                            "arn:aws:lambda:us-east-2:1234:layer:my-layer:2"
                        },
                    ],
                    "Environment": {
                        "Variables": {
                            "NODE_OPTIONS": "-r @sentry/serverless/dist/auto",
                            "SENTRY_DSN": self.sentry_dsn,
                            "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                            "OTHER": "hi",
                        }
                    },
                },
            })
        mock_client.update_function_configuration = MagicMock()
        return_value = {
            "name": "lambdaD",
            "runtime": "nodejs10.x",
            "version": 3,
            "outOfDate": False,
            "enabled": True,
        }
        mock_get_serialized_lambda_function.return_value = return_value

        assert self.get_response(action="updateVersion",
                                 target="lambdaD").data == return_value

        mock_client.get_function.assert_called_with(FunctionName="lambdaD")

        mock_client.update_function_configuration.assert_called_with(
            FunctionName="lambdaD",
            Layers=[
                {
                    "Arn":
                    "arn:aws:lambda:us-east-2:1234:layer:something-else:2"
                },
                "arn:aws:lambda:us-east-2:1234:layer:my-layer:3",
            ],
        )
예제 #3
0
    def test_lambda_setup_layer_too_many_requests_exception(
        self, mock_react_view, mock_gen_aws_client, mock_get_supported_functions
    ):
        class MockException(Exception):
            pass

        too_many_requests_err = (
            "An error occurred (TooManyRequestsException) when calling the "
            "UpdateFunctionConfiguration operation (reached max retries: 4): "
            "Rate exceeded"
        )
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client
        mock_client.update_function_configuration = MagicMock(
            side_effect=Exception(too_many_requests_err)
        )
        mock_client.describe_account = MagicMock(return_value={"Account": {"Name": "my_name"}})
        mock_client.exceptions = MagicMock()
        mock_client.exceptions.ResourceConflictException = MockException

        mock_get_supported_functions.return_value = [
            {
                "FunctionName": "lambdaB",
                "Runtime": "nodejs10.x",
                "FunctionArn": "arn:aws:lambda:us-east-2:599817902985:function:lambdaB",
            },
        ]

        aws_external_id = "12-323"
        self.pipeline.state.step_index = 2
        self.pipeline.state.data = {
            "region": region,
            "account_number": account_number,
            "aws_external_id": aws_external_id,
            "project_id": self.projectA.id,
        }

        resp = self.client.post(
            self.setup_path,
            {"lambdaB": True},
            format="json",
            HTTP_ACCEPT="application/json",
            headers={"Content-Type": "application/json", "Accept": "application/json"},
        )

        assert resp.status_code == 200
        assert not Integration.objects.filter(provider=self.provider.key).exists()

        failures = [
            {
                "name": "lambdaB",
                "error": "Something went wrong! Please enable function manually after installation",
            }
        ]

        mock_react_view.assert_called_with(
            ANY, "awsLambdaFailureDetails", {"lambdaFunctionFailures": failures, "successCount": 0}
        )
예제 #4
0
    def test_lambda_setup_layer_missing_role_error(
        self, mock_react_view, mock_gen_aws_client, mock_get_supported_functions
    ):
        class MockException(Exception):
            pass

        missing_role_err = (
            "An error occurred (InvalidParameterValueException) when "
            "calling the UpdateFunctionConfiguration operation: "
            "The role defined for the function cannot be "
            "assumed by Lambda."
        )
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client
        mock_client.update_function_configuration = MagicMock(
            side_effect=Exception(missing_role_err)
        )
        mock_client.describe_account = MagicMock(return_value={"Account": {"Name": "my_name"}})
        mock_client.exceptions = MagicMock()
        mock_client.exceptions.ResourceConflictException = MockException

        mock_get_supported_functions.return_value = [
            {
                "FunctionName": "lambdaB",
                "Runtime": "nodejs10.x",
                "FunctionArn": "arn:aws:lambda:us-east-2:599817902985:function:lambdaB",
            },
        ]

        aws_external_id = "12-323"
        self.pipeline.state.step_index = 2
        self.pipeline.state.data = {
            "region": region,
            "account_number": account_number,
            "aws_external_id": aws_external_id,
            "project_id": self.projectA.id,
        }

        resp = self.client.post(
            self.setup_path,
            {"lambdaB": True},
            format="json",
            HTTP_ACCEPT="application/json",
            headers={"Content-Type": "application/json", "Accept": "application/json"},
        )

        assert resp.status_code == 200
        assert not Integration.objects.filter(provider=self.provider.key).exists()

        failures = [
            {"name": "lambdaB", "error": "Invalid role associated with the lambda function"}
        ]

        mock_react_view.assert_called_with(
            ANY, "awsLambdaFailureDetails", {"lambdaFunctionFailures": failures, "successCount": 0}
        )
예제 #5
0
    def test_lambda_setup_layer_error(
        self, mock_react_view, mock_gen_aws_client, mock_get_supported_functions
    ):
        class MockException(Exception):
            pass

        bad_layer = "arn:aws:lambda:us-east-2:546545:layer:another-layer:5"
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client
        mock_client.update_function_configuration = MagicMock(
            side_effect=Exception(f"Layer version {bad_layer} does not exist")
        )
        mock_client.describe_account = MagicMock(return_value={"Account": {"Name": "my_name"}})
        mock_client.exceptions = MagicMock()
        mock_client.exceptions.ResourceConflictException = MockException

        mock_get_supported_functions.return_value = [
            {
                "FunctionName": "lambdaA",
                "Runtime": "nodejs12.x",
                "FunctionArn": "arn:aws:lambda:us-east-2:599817902985:function:lambdaA",
            },
            {
                "FunctionName": "lambdaB",
                "Runtime": "nodejs10.x",
                "FunctionArn": "arn:aws:lambda:us-east-2:599817902985:function:lambdaB",
            },
        ]

        aws_external_id = "12-323"
        self.pipeline.state.step_index = 2
        self.pipeline.state.data = {
            "region": region,
            "account_number": account_number,
            "aws_external_id": aws_external_id,
            "project_id": self.projectA.id,
        }

        resp = self.client.post(
            self.setup_path,
            {"lambdaB": True},
            format="json",
            HTTP_ACCEPT="application/json",
            headers={"Content-Type": "application/json", "Accept": "application/json"},
        )

        assert resp.status_code == 200
        assert not Integration.objects.filter(provider=self.provider.key).exists()

        failures = [{"name": "lambdaB", "error": "Invalid existing layer another-layer"}]

        mock_react_view.assert_called_with(
            ANY, "awsLambdaFailureDetails", {"lambdaFunctionFailures": failures, "successCount": 0}
        )
    def test_enable_python_layer_on_already_enabled(
            self, mock_gen_aws_client, mock_get_serialized_lambda_function):
        """
        Test that ensures that if sentry-sdk is already enabled, then
        re-enabling it should not override the env variables since it could be
        problematic since the SENTRY_INITIAL_HANDLER env variable could be overriden
        the second time with "sentry_sdk.integrations.init_serverless_sdk.
        sentry_lambda_handler" and then disabling the sentry-sdk, would break
        the function because the Handler will be updated with an incorrect
        SENTRY_INITIAL_HANDLER value
        """
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client

        mock_client.get_function = MagicMock(
            return_value={
                "Configuration": {
                    "FunctionName":
                    "lambdaZ",
                    "Runtime":
                    "python3.8",
                    "Handler":
                    "sentry_sdk.integrations.init_serverless_sdk.sentry_lambda_handler",
                    "FunctionArn":
                    "arn:aws:lambda:us-east-2:599817902985:function:lambdaZ",
                    "Layers": [
                        "arn:aws:lambda:us-east-2:1234:layer:something-else:2",
                        "arn:aws:lambda:us-east-2:1234:layer:my-python-layer:34",
                    ],
                    "Environment": {
                        "Variables": {
                            "SENTRY_INITIAL_HANDLER":
                            "lambda_handler.test_handler",
                            "SENTRY_DSN": self.sentry_dsn,
                            "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                        }
                    },
                },
            })
        mock_client.update_function_configuration = MagicMock()
        return_value = {
            "name": "lambdaZ",
            "runtime": "python3.8",
            "version": 3,
            "outOfDate": False,
            "enabled": True,
        }
        mock_get_serialized_lambda_function.return_value = return_value

        assert self.get_response(action="enable",
                                 target="lambdaZ").data == return_value

        mock_client.get_function.assert_called_with(FunctionName="lambdaZ")

        mock_client.update_function_configuration.assert_called_with(
            FunctionName="lambdaZ",
            Layers=[
                "arn:aws:lambda:us-east-2:1234:layer:something-else:2",
                "arn:aws:lambda:us-east-2:1234:layer:my-python-layer:34",
            ],
            Environment={
                "Variables": {
                    "SENTRY_INITIAL_HANDLER": "lambda_handler.test_handler",
                    "SENTRY_DSN": self.sentry_dsn,
                    "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                }
            },
            Handler=
            "sentry_sdk.integrations.init_serverless_sdk.sentry_lambda_handler",
        )
예제 #7
0
    def test_lambda_setup_layer_success(self, mock_gen_aws_client,
                                        mock_get_supported_functions):
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client
        mock_client.update_function_configuration = MagicMock()
        mock_client.describe_account = MagicMock(
            return_value={"Account": {
                "Name": "my_name"
            }})

        mock_get_supported_functions.return_value = [
            {
                "FunctionName":
                "lambdaA",
                "Runtime":
                "nodejs12.x",
                "FunctionArn":
                "arn:aws:lambda:us-east-2:599817902985:function:lambdaA",
            },
            {
                "FunctionName":
                "lambdaB",
                "Runtime":
                "nodejs10.x",
                "FunctionArn":
                "arn:aws:lambda:us-east-2:599817902985:function:lambdaB",
            },
        ]

        aws_external_id = "12-323"
        self.pipeline.state.step_index = 2
        self.pipeline.state.data = {
            "arn": arn,
            "aws_external_id": aws_external_id,
            "project_id": self.projectA.id,
        }

        sentry_project_dsn = ProjectKey.get_default(
            project=self.projectA).get_dsn(public=True)

        resp = self.client.post(
            self.setup_path,
            {"lambdaB": True},
            format="json",
            HTTP_ACCEPT="application/json",
            headers={
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
        )

        assert resp.status_code == 200

        mock_client.update_function_configuration.assert_called_with(
            FunctionName="lambdaB",
            Layers=["arn:aws:lambda:us-east-2:1234:layer:my-layer:3"],
            Environment={
                "Variables": {
                    "NODE_OPTIONS": "-r @sentry/serverless/dist/auto",
                    "SENTRY_DSN": sentry_project_dsn,
                    "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                }
            },
        )

        integration = Integration.objects.get(provider=self.provider.key)
        assert integration.name == "my_name us-east-2"
        assert integration.external_id == "599817902985-us-east-2"
        assert integration.metadata == {
            "arn": arn,
            "aws_external_id": aws_external_id
        }
        assert OrganizationIntegration.objects.filter(
            integration=integration, organization=self.organization)
예제 #8
0
    def test_lambda_setup_layer_env_vars_limit_exceeded_exception(
            self, mock_react_view, mock_gen_aws_client,
            mock_get_supported_functions):
        class MockException(Exception):
            pass

        env_vars_size_limit_err = (
            "An error occurred (InvalidParameterValueException) when calling the "
            "UpdateFunctionConfiguration operation: Lambda was unable to configure "
            "your environment variables because the environment variables you have "
            "provided exceeded the 4KB limit. String measured: {'MESSAGE':'This is production "
            "environment','TARGET_ENV' :'pre-production','IS_SERVERLESS':'true','STAGE':'pre-prod'"
        )
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client
        mock_client.update_function_configuration = MagicMock(
            side_effect=Exception(env_vars_size_limit_err))
        mock_client.describe_account = MagicMock(
            return_value={"Account": {
                "Name": "my_name"
            }})
        mock_client.exceptions = MagicMock()
        mock_client.exceptions.ResourceConflictException = MockException

        mock_get_supported_functions.return_value = [
            {
                "FunctionName":
                "lambdaB",
                "Runtime":
                "nodejs10.x",
                "FunctionArn":
                "arn:aws:lambda:us-east-2:599817902985:function:lambdaB",
            },
        ]

        aws_external_id = "12-323"
        self.pipeline.state.step_index = 2
        self.pipeline.state.data = {
            "region": region,
            "account_number": account_number,
            "aws_external_id": aws_external_id,
            "project_id": self.projectA.id,
        }

        resp = self.client.post(
            self.setup_path,
            {"lambdaB": True},
            format="json",
            HTTP_ACCEPT="application/json",
            headers={
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
        )

        assert resp.status_code == 200
        assert not Integration.objects.filter(
            provider=self.provider.key).exists()

        failures = [{
            "name":
            "lambdaB",
            "error":
            "Environment variables size limit of 4KB was exceeded",
        }]

        mock_react_view.assert_called_with(ANY, "awsLambdaFailureDetails", {
            "lambdaFunctionFailures": failures,
            "successCount": 0
        })
예제 #9
0
    def test_python_lambda_setup_layer_success(self, mock_gen_aws_client,
                                               mock_get_supported_functions):
        mock_client = Mock()
        mock_gen_aws_client.return_value = mock_client
        mock_client.update_function_configuration = MagicMock()
        mock_client.describe_account = MagicMock(
            return_value={"Account": {
                "Name": "my_name"
            }})

        mock_get_supported_functions.return_value = [{
            "FunctionName":
            "lambdaA",
            "Handler":
            "lambda_handler.test_handler",
            "Runtime":
            "python3.6",
            "FunctionArn":
            "arn:aws:lambda:us-east-2:599817902985:function:lambdaA",
        }]

        aws_external_id = "12-323"
        self.pipeline.state.step_index = 2
        self.pipeline.state.data = {
            "region": region,
            "account_number": account_number,
            "aws_external_id": aws_external_id,
            "project_id": self.projectA.id,
        }

        sentry_project_dsn = ProjectKey.get_default(
            project=self.projectA).get_dsn(public=True)

        resp = self.client.post(
            self.setup_path,
            data={"lambdaA": True},
            format="json",
            HTTP_ACCEPT="application/json",
            headers={
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
        )

        assert resp.status_code == 200

        mock_client.update_function_configuration.assert_called_once_with(
            FunctionName="lambdaA",
            Layers=["arn:aws:lambda:us-east-2:1234:layer:my-python-layer:34"],
            Environment={
                "Variables": {
                    "SENTRY_INITIAL_HANDLER": "lambda_handler.test_handler",
                    "SENTRY_DSN": sentry_project_dsn,
                    "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                }
            },
            Handler=
            "sentry_sdk.integrations.init_serverless_sdk.sentry_lambda_handler",
        )

        integration = Integration.objects.get(provider=self.provider.key)
        assert integration.name == "my_name us-east-2"
        assert integration.external_id == "599817902985-us-east-2"
        assert integration.metadata == {
            "region": region,
            "account_number": account_number,
            "aws_external_id": aws_external_id,
        }
        assert OrganizationIntegration.objects.filter(
            integration=integration, organization=self.organization)