Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def on_before_transform_template(self, template_dict):

if key not in self._applications:
try:
if not RegionConfiguration.is_sar_supported():
if not RegionConfiguration.is_service_supported("serverlessrepo"):
raise InvalidResourceException(
logical_id, "Serverless Application Repository is not available in this region."
)
Expand Down
37 changes: 19 additions & 18 deletions samtranslator/region_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,32 @@ def is_apigw_edge_configuration_supported(cls):
]

@classmethod
def is_sar_supported(cls):
def is_service_supported(cls, service, region=None):
"""
SAR is not supported in some regions.
Not all services are supported in all regions. This method returns whether a given
service is supported in a given region. If no region is specified, the current region
(as identified by boto3) is used.
https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/
https://docs.aws.amazon.com/general/latest/gr/serverlessrepo.html

:return: True, if SAR is supported in current region.
:param service: service code (string used to obtain a boto3 client for the service)
:param region: region identifier (e.g., us-east-1)
:return: True, if the service is supported in the region
"""

session = boto3.Session()

# get the current region
region = session.region_name
if not region:
# get the current region
region = session.region_name

# need to handle when region is None so that it won't break
if region is None:
if ArnGenerator.BOTO_SESSION_REGION_NAME is not None:
region = ArnGenerator.BOTO_SESSION_REGION_NAME
else:
raise NoRegionFound("AWS Region cannot be found")
# need to handle when region is None so that it won't break
if region is None:
if ArnGenerator.BOTO_SESSION_REGION_NAME is not None:
region = ArnGenerator.BOTO_SESSION_REGION_NAME
else:
raise NoRegionFound("AWS Region cannot be found")

# boto3 get_available_regions call won't return us-gov and cn regions even if SAR is available
if region.startswith("cn") or region.startswith("us-gov"):
return True

# get all regions where SAR are available
available_regions = session.get_available_regions("serverlessrepo")
# check if the service is available in region
partition = session.get_partition_for_region(region)
available_regions = session.get_available_regions(service, partition_name=partition)
return region in available_regions
24 changes: 24 additions & 0 deletions tests/unit/test_region_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,27 @@ def test_when_apigw_edge_configuration_is_not_supported(self, partition):
get_partition_name_patch.return_value = partition

self.assertFalse(RegionConfiguration.is_apigw_edge_configuration_supported())

@parameterized.expand(
[
# use ec2 as it's just about everywhere
["ec2", "cn-north-1"],
["ec2", "us-west-2"],
["ec2", "us-gov-east-1"],
["ec2", "us-isob-east-1"],
["ec2", None],
# test SAR since SAM uses that
["serverlessrepo", "us-east-1"],
["serverlessrepo", "ap-southeast-2"],
]
)
def test_is_service_supported_positive(self, service, region):
self.assertTrue(RegionConfiguration.is_service_supported(service, region))

def test_is_service_supported_negative(self):
# use an unknown service name
self.assertFalse(RegionConfiguration.is_service_supported("ec1", "us-east-1"))
# use a region that does not exist
self.assertFalse(RegionConfiguration.is_service_supported("ec2", "us-east-0"))
# hard to test with a real service, since the test may start failing once that
# service is rolled out to more regions...