Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Intrinsics #1333

Merged
merged 12 commits into from
Aug 14, 2019
42 changes: 21 additions & 21 deletions samcli/commands/local/lib/sam_base_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
from samtranslator.intrinsics.resolver import IntrinsicsResolver
from samtranslator.intrinsics.actions import RefAction

from samcli.lib.intrinsic_resolver.intrinsics_symbol_table import IntrinsicsSymbolTable
from samcli.lib.intrinsic_resolver.intrinsic_property_resolver import IntrinsicResolver

from samcli.lib.samlib.wrapper import SamTranslatorWrapper
from samcli.lib.samlib.resource_metadata_normalizer import ResourceMetadataNormalizer

Expand All @@ -18,21 +21,6 @@ class SamBaseProvider(object):
Base class for SAM Template providers
"""

# There is not much benefit in infering real values for these parameters in local development context. These values
# are usually representative of an AWS environment and stack, but in local development scenario they don't make
# sense. If customers choose to, they can always override this value through the CLI interface.
DEFAULT_PSEUDO_PARAM_VALUES = {
"AWS::AccountId": "123456789012",
"AWS::Partition": "aws",

"AWS::Region": "us-east-1",

"AWS::StackName": "local",
"AWS::StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/"
"local/51af3dc0-da77-11e4-872e-1234567db123",
"AWS::URLSuffix": "localhost"
}

# Only Ref is supported when resolving template parameters
_SUPPORTED_INTRINSICS = [RefAction]

Expand Down Expand Up @@ -60,8 +48,14 @@ def get_template(template_dict, parameter_overrides=None):
if template_dict:
template_dict = SamTranslatorWrapper(template_dict).run_plugins()

template_dict = SamBaseProvider._resolve_parameters(template_dict, parameter_overrides)
template_dict = SamBaseProvider._resolve_parameters(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed anymore since we have the full resolver now?

template_dict, parameter_overrides
)
ResourceMetadataNormalizer.normalize(template_dict)
resolver = IntrinsicResolver(
template=template_dict, symbol_resolver=IntrinsicsSymbolTable()
)
template_dict["Resources"] = resolver.resolve_template(ignore_errors=True)
return template_dict

@staticmethod
Expand All @@ -83,13 +77,19 @@ def _resolve_parameters(template_dict, parameter_overrides):
Resolved SAM template
"""

parameter_values = SamBaseProvider._get_parameter_values(template_dict, parameter_overrides)
parameter_values = SamBaseProvider._get_parameter_values(
template_dict, parameter_overrides
)

supported_intrinsics = {action.intrinsic_name: action() for action in SamBaseProvider._SUPPORTED_INTRINSICS}
supported_intrinsics = {
action.intrinsic_name: action()
for action in SamBaseProvider._SUPPORTED_INTRINSICS
}

# Intrinsics resolver will mutate the original template
return IntrinsicsResolver(parameters=parameter_values, supported_intrinsics=supported_intrinsics) \
.resolve_parameter_refs(template_dict)
return IntrinsicsResolver(
parameters=parameter_values, supported_intrinsics=supported_intrinsics
).resolve_parameter_refs(template_dict)

@staticmethod
def _get_parameter_values(template_dict, parameter_overrides):
Expand All @@ -116,7 +116,7 @@ def _get_parameter_values(template_dict, parameter_overrides):
# NOTE: Ordering of following statements is important. It makes sure that any user-supplied values
# override the defaults
parameter_values = {}
parameter_values.update(SamBaseProvider.DEFAULT_PSEUDO_PARAM_VALUES)
parameter_values.update(IntrinsicsSymbolTable.DEFAULT_PSEUDO_PARAM_VALUES)
parameter_values.update(default_values)
parameter_values.update(parameter_overrides or {})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ def handle_fn_get_azs(self, intrinsic_value):
verify_intrinsic_type_str(intrinsic_value, IntrinsicResolver.FN_GET_AZS)

if intrinsic_value == "":
intrinsic_value = self._symbol_resolver.DEFAULT_REGION
intrinsic_value = self._symbol_resolver.handle_pseudo_region()

if intrinsic_value not in self._symbol_resolver.REGIONS:
raise InvalidIntrinsicException(
Expand Down
23 changes: 17 additions & 6 deletions samcli/lib/intrinsic_resolver/intrinsics_symbol_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from six import string_types

from samcli.commands.local.lib.sam_base_provider import SamBaseProvider
from samcli.lib.intrinsic_resolver.intrinsic_property_resolver import IntrinsicResolver
from samcli.lib.intrinsic_resolver.invalid_intrinsic_exception import (
InvalidSymbolException,
Expand All @@ -32,7 +31,19 @@ class IntrinsicsSymbolTable(object):
AWS_NOVALUE,
]

DEFAULT_REGION = "us-east-1"
# There is not much benefit in infering real values for these parameters in local development context. These values
# are usually representative of an AWS environment and stack, but in local development scenario they don't make
# sense. If customers choose to, they can always override this value through the CLI interface.
DEFAULT_PSEUDO_PARAM_VALUES = {
"AWS::AccountId": "123456789012",
"AWS::Partition": "aws",
"AWS::Region": "us-east-1",
"AWS::StackName": "local",
"AWS::StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/"
"local/51af3dc0-da77-11e4-872e-1234567db123",
"AWS::URLSuffix": "localhost",
}

REGIONS = {
"us-east-1": [
"us-east-1a",
Expand Down Expand Up @@ -322,7 +333,7 @@ def handle_pseudo_account_id():
-------
A pseudo account id
"""
return SamBaseProvider.DEFAULT_PSEUDO_PARAM_VALUES.get(
return IntrinsicsSymbolTable.DEFAULT_PSEUDO_PARAM_VALUES.get(
IntrinsicsSymbolTable.AWS_ACCOUNT_ID
)

Expand All @@ -338,7 +349,7 @@ def handle_pseudo_region(self):
"""
return (
self.logical_id_translator.get(IntrinsicsSymbolTable.AWS_REGION) or os.getenv("AWS_REGION") or
SamBaseProvider.DEFAULT_PSEUDO_PARAM_VALUES.get(
IntrinsicsSymbolTable.DEFAULT_PSEUDO_PARAM_VALUES.get(
IntrinsicsSymbolTable.AWS_REGION
)
)
Expand Down Expand Up @@ -385,7 +396,7 @@ def handle_pseudo_stack_id():
-------
A randomized string
"""
return SamBaseProvider.DEFAULT_PSEUDO_PARAM_VALUES.get(
return IntrinsicsSymbolTable.DEFAULT_PSEUDO_PARAM_VALUES.get(
IntrinsicsSymbolTable.AWS_STACK_ID
)

Expand All @@ -400,7 +411,7 @@ def handle_pseudo_stack_name():
-------
A randomized string
"""
return SamBaseProvider.DEFAULT_PSEUDO_PARAM_VALUES.get(
return IntrinsicsSymbolTable.DEFAULT_PSEUDO_PARAM_VALUES.get(
IntrinsicsSymbolTable.AWS_STACK_NAME
)

Expand Down
27 changes: 27 additions & 0 deletions tests/integration/local/start_api/test_start_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ class TestStartApiWithMethodsAndResources(StartApiIntegBaseClass):
def setUp(self):
self.url = "http://127.0.0.1:{}".format(self.port)


def test_get_call_with_path_setup_with_any_swagger(self):
"""
Get Request to a path that was defined as ANY in SAM through Swagger
Expand All @@ -769,6 +770,8 @@ def test_get_call_with_path_setup_with_any_swagger(self):
self.assertEquals(response.status_code, 200)
self.assertEquals(response.json(), {'hello': 'world'})

self.assertEquals(response_data.get("stageVariables"), {"Stack": "Dev"})

def test_post_call_with_path_setup_with_any_swagger(self):
"""
Post Request to a path that was defined as ANY in SAM through Swagger
Expand Down Expand Up @@ -866,3 +869,27 @@ def test_proxy_response(self):

self.assertEquals(response.status_code, 200)
self.assertEquals(response.json(), {'hello': 'world'})

class TestCDKApiGateway(StartApiIntegBaseClass):
template_path = "/testdata/start_api/cdk-sample-output.yaml"

def setUp(self):
self.url = "http://127.0.0.1:{}".format(self.port)

def test_get_with_cdk(self):
"""
Get Request to a path that was defined as ANY in SAM through Swagger
"""
response = requests.get(self.url + "/hello-world")

class TestServerlessApiGateway(StartApiIntegBaseClass):
template_path = "/testdata/start_api/serverless-sample-output.yaml"

def setUp(self):
self.url = "http://127.0.0.1:{}".format(self.port)

def test_get_with_serverless(self):
"""
Get Request to a path that was defined as ANY in SAM through Swagger
"""
response = requests.get(self.url + "/hello-world")
Loading