def test_api_provider_sam_function(self):
        resources = {
            "TestApi": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    "StageName": "dev",
                    "DefinitionBody": {
                        "paths": {
                            "/path": {
                                "get": {
                                    "x-amazon-apigateway-integration": {
                                        "httpMethod": "POST",
                                        "type": "aws_proxy",
                                        "uri": {
                                            "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
                                            "/functions/${NoApiEventFunction.Arn}/invocations"
                                        },
                                        "responses": {},
                                    }
                                }
                            }
                        }
                    },
                },
            }
        }

        provider = ApiProvider.find_api_provider(resources)

        self.assertTrue(isinstance(provider, SamApiProvider))
Esempio n. 2
0
    def test_provider_parse_stage_name(self):
        template = {
            "Resources": {
                "Stage": {"Type": "AWS::ApiGateway::Stage", "Properties": {"StageName": "dev", "RestApiId": "TestApi"}},
                "TestApi": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {
                        "Body": {
                            "paths": {
                                "/path": {
                                    "get": {
                                        "x-amazon-apigateway-integration": {
                                            "httpMethod": "POST",
                                            "type": "aws_proxy",
                                            "uri": {
                                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
                                                "/functions/${NoApiEventFunction.Arn}/invocations"
                                            },
                                            "responses": {},
                                        }
                                    }
                                }
                            }
                        }
                    },
                },
            }
        }
        provider = ApiProvider(template)
        route1 = Route(path="/path", methods=["GET"], function_name="NoApiEventFunction")

        self.assertIn(route1, provider.routes)
        self.assertEqual(provider.api.stage_name, "dev")
        self.assertEqual(provider.api.stage_variables, None)
Esempio n. 3
0
 def test_resource_with_method_correct_routes(self):
     template = {
         "Resources": {
             "TestApi": {"Type": "AWS::ApiGateway::Resource", "Properties": {"StageName": "Prod"}},
             "BetaApiResource": {
                 "Type": "AWS::ApiGateway::Resource",
                 "Properties": {"PathPart": "beta", "ResourceId": "TestApi"},
             },
             "BetaAlphaApiMethod": {
                 "Type": "AWS::ApiGateway::Method",
                 "Properties": {"HttpMethod": "ANY", "RestApiId": "TestApi", "ResourceId": "BetaApiResource"},
             },
         }
     }
     provider = ApiProvider(template)
     self.assertCountEqual(
         provider.routes,
         [
             Route(
                 path="/beta",
                 methods=["POST", "GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "PUT"],
                 function_name=None,
             )
         ],
     )
Esempio n. 4
0
    def test_with_inline_swagger_apis(self):
        template = {
            "Resources": {
                "Api1": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"Body": make_swagger(self.input_routes)}}
            }
        }

        provider = ApiProvider(template)
        self.assertCountEqual(self.input_routes, provider.routes)
    def test_provider_with_valid_template(self, SamBaseProviderMock, extract_api_mock):
        extract_api_mock.return_value = Api(routes={"set", "of", "values"})
        template = {"Resources": {"a": "b"}}
        SamBaseProviderMock.get_template.return_value = template

        provider = ApiProvider(template)
        self.assertEqual(len(provider.routes), 3)
        self.assertEqual(provider.routes, set(["set", "of", "values"]))

        self.assertEqual(provider.template_dict, {"Resources": {"a": "b"}})
        self.assertEqual(provider.resources, {"a": "b"})
Esempio n. 6
0
    def test_basic_rest_api_resource_method(self):
        template = {
            "Resources": {
                "TestApi": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"StageName": "Prod"}},
                "ApiResource": {"Properties": {"PathPart": "{proxy+}", "RestApiId": "TestApi"}},
                "ApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {"HttpMethod": "POST", "RestApiId": "TestApi", "ResourceId": "ApiResource"},
                },
            }
        }

        provider = ApiProvider(template)

        self.assertEqual(provider.routes, [Route(function_name=None, path="/{proxy+}", methods=["POST"])])
Esempio n. 7
0
    def test_with_swagger_as_local_file(self):
        with tempfile.NamedTemporaryFile(mode="w", delete=False) as fp:
            filename = fp.name

            swagger = make_swagger(self.input_routes)

            json.dump(swagger, fp)
            fp.flush()

            template = {
                "Resources": {"Api1": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"BodyS3Location": filename}}}
            }

            provider = ApiProvider(template)
            self.assertCountEqual(self.input_routes, provider.routes)
Esempio n. 8
0
    def test_with_swagger_as_both_body_and_uri_called(self, SwaggerReaderMock):
        body = {"some": "body"}
        filename = "somefile.txt"

        template = {
            "Resources": {
                "Api1": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"BodyS3Location": filename, "Body": body}}
            }
        }

        SwaggerReaderMock.return_value.read.return_value = make_swagger(self.input_routes)

        cwd = "foo"
        provider = ApiProvider(template, cwd=cwd)
        self.assertCountEqual(self.input_routes, provider.routes)
        SwaggerReaderMock.assert_called_with(definition_body=body, definition_uri=filename, working_dir=cwd)
Esempio n. 9
0
    def test_swagger_with_any_method(self):
        routes = [Route(path="/path", methods=["any"], function_name="SamFunc1")]

        expected_routes = [
            Route(
                path="/path",
                methods=["GET", "DELETE", "PUT", "POST", "HEAD", "OPTIONS", "PATCH"],
                function_name="SamFunc1",
            )
        ]

        template = {
            "Resources": {"Api1": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"Body": make_swagger(routes)}}}
        }

        provider = ApiProvider(template)
        self.assertCountEqual(expected_routes, provider.routes)
Esempio n. 10
0
    def test_with_binary_media_types(self):
        template = {
            "Resources": {
                "Api1": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {"Body": make_swagger(self.input_routes, binary_media_types=self.binary_types)},
                }
            }
        }

        expected_binary_types = sorted(self.binary_types)
        expected_apis = [
            Route(path="/path1", methods=["GET", "POST"], function_name="SamFunc1"),
            Route(path="/path2", methods=["PUT", "GET"], function_name="SamFunc1"),
            Route(path="/path3", methods=["DELETE"], function_name="SamFunc1"),
        ]

        provider = ApiProvider(template)
        self.assertCountEqual(expected_apis, provider.routes)
        self.assertCountEqual(provider.api.binary_media_types, expected_binary_types)
Esempio n. 11
0
    def test_resolve_correct_multi_parent_resource_path(self):
        template = {
            "Resources": {
                "TestApi": {"Type": "AWS::ApiGateway::Resource", "Properties": {"StageName": "Prod"}},
                "RootApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "root", "ResourceId": "TestApi"},
                },
                "V1ApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "v1", "ResourceId": "TestApi", "ParentId": "RootApiResource"},
                },
                "AlphaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "alpha", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "BetaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "beta", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "AlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {"HttpMethod": "GET", "RestApiId": "TestApi", "ResourceId": "AlphaApiResource"},
                },
                "BetaAlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {"HttpMethod": "POST", "RestApiId": "TestApi", "ResourceId": "BetaApiResource"},
                },
            }
        }

        provider = ApiProvider(template)
        assertCountEqual(
            self,
            provider.routes,
            [
                Route(path="/root/v1/beta", methods=["POST"], function_name=None),
                Route(path="/root/v1/alpha", methods=["GET"], function_name=None),
            ],
        )
Esempio n. 12
0
    def __init__(self, lambda_invoke_context, port, host, static_dir):
        """
        Initialize the local API service.

        :param samcli.commands.local.cli_common.invoke_context.InvokeContext lambda_invoke_context: Context object
            that can help with Lambda invocation
        :param int port: Port to listen on
        :param string host: Local hostname or IP address to bind to
        :param string static_dir: Optional, directory from which static files will be mounted
        """

        self.port = port
        self.host = host
        self.static_dir = static_dir

        self.cwd = lambda_invoke_context.get_cwd()
        self.api_provider = ApiProvider(
            lambda_invoke_context.template,
            parameter_overrides=lambda_invoke_context.parameter_overrides,
            cwd=self.cwd)
        self.lambda_runner = lambda_invoke_context.local_lambda_runner
        self.stderr_stream = lambda_invoke_context.stderr
Esempio n. 13
0
    def test_with_binary_media_types_in_swagger_and_on_resource(self):
        input_routes = [Route(path="/path", methods=["OPTIONS"], function_name="SamFunc1")]
        extra_binary_types = ["text/html"]

        template = {
            "Resources": {
                "Api1": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {
                        "BinaryMediaTypes": extra_binary_types,
                        "Body": make_swagger(input_routes, binary_media_types=self.binary_types),
                    },
                }
            }
        }

        expected_binary_types = sorted(self.binary_types + extra_binary_types)
        expected_routes = [Route(path="/path", methods=["OPTIONS"], function_name="SamFunc1")]

        provider = ApiProvider(template)
        self.assertCountEqual(expected_routes, provider.routes)
        self.assertCountEqual(provider.api.binary_media_types, expected_binary_types)
Esempio n. 14
0
 def test_cdk(self):
     template = {
         "AWSTemplateFormatVersion": "2010-09-09",
         "Resources": {
             "HelloHandler2E4FBA4D": {
                 "Type": "AWS::Lambda::Function",
                 "Properties": {"Code": ".", "Handler": "main.handler", "Runtime": "python3.6"},
                 "DependsOn": ["HelloHandlerServiceRole11EF7C63"],
             },
             "EndpointEEF1FD8F": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"Name": "Endpoint"}},
             "EndpointDeploymentStageprodB78BEEA0": {
                 "Type": "AWS::ApiGateway::Stage",
                 "Properties": {
                     "RestApiId": {"Ref": "EndpointEEF1FD8F"},
                     "DeploymentId": {"Ref": "EndpointDeployment318525DA37c0e38727e25b4317827bf43e918fbf"},
                     "StageName": "prod",
                 },
             },
             "Endpointproxy39E2174E": {
                 "Type": "AWS::ApiGateway::Resource",
                 "Properties": {
                     "ParentId": {"Fn::GetAtt": ["EndpointEEF1FD8F", "RootResourceId"]},
                     "PathPart": "{proxy+}",
                     "RestApiId": {"Ref": "EndpointEEF1FD8F"},
                 },
             },
             "EndpointproxyANYC09721C5": {
                 "Type": "AWS::ApiGateway::Method",
                 "Properties": {
                     "HttpMethod": "ANY",
                     "ResourceId": {"Ref": "Endpointproxy39E2174E"},
                     "RestApiId": {"Ref": "EndpointEEF1FD8F"},
                     "AuthorizationType": "NONE",
                     "Integration": {
                         "IntegrationHttpMethod": "POST",
                         "Type": "AWS_PROXY",
                         "Uri": {
                             "Fn::Join": [
                                 "",
                                 [
                                     "arn:",
                                     {"Ref": "AWS::Partition"},
                                     ":apigateway:",
                                     {"Ref": "AWS::Region"},
                                     "lambda:path/2015-03-31/functions/",
                                     {"Fn::GetAtt": ["HelloHandler2E4FBA4D", "Arn"]},
                                     "/invocations",
                                 ],
                             ]
                         },
                     },
                 },
             },
             "EndpointANY485C938B": {
                 "Type": "AWS::ApiGateway::Method",
                 "Properties": {
                     "HttpMethod": "ANY",
                     "ResourceId": {"Fn::GetAtt": ["EndpointEEF1FD8F", "RootResourceId"]},
                     "RestApiId": {"Ref": "EndpointEEF1FD8F"},
                     "AuthorizationType": "NONE",
                     "Integration": {
                         "IntegrationHttpMethod": "POST",
                         "Type": "AWS_PROXY",
                         "Uri": {
                             "Fn::Join": [
                                 "",
                                 [
                                     "arn:",
                                     {"Ref": "AWS::Partition"},
                                     ":apigateway:",
                                     {"Ref": "AWS::Region"},
                                     "lambda:path/2015-03-31/functions/",
                                     {"Fn::GetAtt": ["HelloHandler2E4FBA4D", "Arn"]},
                                     "/invocations",
                                 ],
                             ]
                         },
                     },
                 },
             },
         },
         "Parameters": {
             "HelloHandlerCodeS3Bucket4359A483": {
                 "Type": "String",
                 "Description": 'S3 bucket for asset "CdkWorkshopStack/HelloHandler/Code"',
             },
             "HelloHandlerCodeS3VersionKey07D12610": {
                 "Type": "String",
                 "Description": 'S3 key for asset version "CdkWorkshopStack/HelloHandler/Code"',
             },
         },
         "Outputs": {
             "Endpoint8024A810": {
                 "Value": {
                     "Fn::Join": [
                         "",
                         [
                             "https://",
                             {"Ref": "EndpointEEF1FD8F"},
                             ".execute-api.",
                             {"Ref": "AWS::Region"},
                             ".",
                             {"Ref": "AWS::URLSuffix"},
                             "/",
                             {"Ref": "EndpointDeploymentStageprodB78BEEA0"},
                             "/",
                         ],
                     ]
                 },
                 "Export": {"Name": "CdkWorkshopStack:Endpoint8024A810"},
             }
         },
     }
     provider = ApiProvider(template)
     proxy_paths = [Route(path="/{proxy+}", methods=Route.ANY_HTTP_METHODS, function_name="HelloHandler2E4FBA4D")]
     root_paths = [Route(path="/", methods=Route.ANY_HTTP_METHODS, function_name="HelloHandler2E4FBA4D")]
     self.assertCountEqual(provider.routes, proxy_paths + root_paths)
Esempio n. 15
0
    def test_binary_media_types_method(self):
        template = {
            "Resources": {
                "TestApi": {"Type": "AWS::ApiGateway::Resource", "Properties": {"StageName": "Prod"}},
                "RootApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "root", "ResourceId": "TestApi"},
                },
                "V1ApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "v1", "ResourceId": "TestApi", "ParentId": "RootApiResource"},
                },
                "AlphaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "alpha", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "BetaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "beta", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "AlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {
                        "HttpMethod": "GET",
                        "RestApiId": "TestApi",
                        "ResourceId": "AlphaApiResource",
                        "Integration": {
                            "Uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/"
                                "functions"
                                "/${AWSBetaLambdaFunction.Arn}/invocations} "
                            },
                            "ContentHandling": "CONVERT_TO_BINARY",
                            "ContentType": "image~1jpg",
                        },
                    },
                },
                "BetaAlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {
                        "HttpMethod": "POST",
                        "RestApiId": "TestApi",
                        "ResourceId": "BetaApiResource",
                        "Integration": {
                            "Uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/"
                                "functions"
                                "/${AWSLambdaFunction.Arn}/invocations}"
                            },
                            "ContentHandling": "CONVERT_TO_BINARY",
                            "ContentType": "image~1png",
                        },
                    },
                },
                "AWSAlphaLambdaFunction": {
                    "Type": "AWS::Lambda::Function",
                    "Properties": {"Code": ".", "Handler": "main.run_test", "Runtime": "Python3.6"},
                },
                "AWSBetaLambdaFunction": {
                    "Type": "AWS::Lambda::Function",
                    "Properties": {"Code": ".", "Handler": "main.run_test", "Runtime": "Python3.6"},
                },
            }
        }

        provider = ApiProvider(template)
        self.assertCountEqual(provider.api.binary_media_types, ["image/png", "image/jpg"])
Esempio n. 16
0
    def test_method_integration_uri(self):
        template = {
            "Resources": {
                "TestApi": {"Type": "AWS::ApiGateway::Resource", "Properties": {"StageName": "Prod"}},
                "RootApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "root", "ResourceId": "TestApi"},
                },
                "V1ApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "v1", "ResourceId": "TestApi", "ParentId": "RootApiResource"},
                },
                "AlphaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "alpha", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "BetaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "beta", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "AlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {
                        "HttpMethod": "GET",
                        "RestApiId": "TestApi",
                        "ResourceId": "AlphaApiResource",
                        "Integration": {
                            "Uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/"
                                "functions"
                                "/${AWSBetaLambdaFunction.Arn}/invocations} "
                            }
                        },
                    },
                },
                "BetaAlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {
                        "HttpMethod": "POST",
                        "RestApiId": "TestApi",
                        "ResourceId": "BetaApiResource",
                        "Integration": {
                            "Uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/"
                                "functions"
                                "/${AWSLambdaFunction.Arn}/invocations}"
                            }
                        },
                    },
                },
                "AWSAlphaLambdaFunction": {
                    "Type": "AWS::Lambda::Function",
                    "Properties": {"Code": ".", "Handler": "main.run_test", "Runtime": "Python3.6"},
                },
                "AWSBetaLambdaFunction": {
                    "Type": "AWS::Lambda::Function",
                    "Properties": {"Code": ".", "Handler": "main.run_test", "Runtime": "Python3.6"},
                },
            }
        }

        provider = ApiProvider(template)
        self.assertCountEqual(
            provider.routes,
            [
                Route(path="/root/v1/beta", methods=["POST"], function_name="AWSLambdaFunction"),
                Route(path="/root/v1/alpha", methods=["GET"], function_name="AWSBetaLambdaFunction"),
            ],
        )
Esempio n. 17
0
    def test_multi_stage_get_all(self):
        resources = OrderedDict(
            {
                "ProductionApi": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {
                        "Body": {
                            "paths": {
                                "/path": {
                                    "get": {
                                        "x-amazon-apigateway-integration": {
                                            "httpMethod": "POST",
                                            "type": "aws_proxy",
                                            "uri": {
                                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
                                                "/functions/${NoApiEventFunction.Arn}/invocations"
                                            },
                                            "responses": {},
                                        }
                                    }
                                },
                                "/anotherpath": {
                                    "post": {
                                        "x-amazon-apigateway-integration": {
                                            "httpMethod": "POST",
                                            "type": "aws_proxy",
                                            "uri": {
                                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
                                                "/functions/${NoApiEventFunction.Arn}/invocations"
                                            },
                                            "responses": {},
                                        }
                                    }
                                },
                            }
                        }
                    },
                }
            }
        )
        resources["StageDev"] = {
            "Type": "AWS::ApiGateway::Stage",
            "Properties": {
                "StageName": "dev",
                "Variables": {"vis": "data", "random": "test", "foo": "bar"},
                "RestApiId": "ProductionApi",
            },
        }
        resources["StageProd"] = {
            "Type": "AWS::ApiGateway::Stage",
            "Properties": {
                "StageName": "Production",
                "Variables": {"vis": "prod data", "random": "test", "foo": "bar"},
                "RestApiId": "ProductionApi",
            },
        }
        template = {"Resources": resources}
        provider = ApiProvider(template)

        result = [f for f in provider.get_all()]
        routes = result[0].routes

        route1 = Route(path="/path", methods=["GET"], function_name="NoApiEventFunction")
        route2 = Route(path="/anotherpath", methods=["POST"], function_name="NoApiEventFunction")
        self.assertEqual(len(routes), 2)
        self.assertIn(route1, routes)
        self.assertIn(route2, routes)

        self.assertEqual(provider.api.stage_name, "Production")
        self.assertEqual(provider.api.stage_variables, {"vis": "prod data", "random": "test", "foo": "bar"})
Esempio n. 18
0
    def test_with_no_apis(self):
        template = {"Resources": {"Api1": {"Type": "AWS::ApiGateway::RestApi", "Properties": {}}}}

        provider = ApiProvider(template)

        self.assertEqual(provider.routes, [])