1import boto3 2 3 4class NoRegionFound(Exception): 5 pass 6 7 8class ArnGenerator(object): 9 BOTO_SESSION_REGION_NAME = None 10 11 @classmethod 12 def generate_arn(cls, partition, service, resource, include_account_id=True): 13 if not service or not resource: 14 raise RuntimeError("Could not construct ARN for resource.") 15 16 arn = "arn:{0}:{1}:${{AWS::Region}}:" 17 18 if include_account_id: 19 arn += "${{AWS::AccountId}}:" 20 21 arn += "{2}" 22 23 return arn.format(partition, service, resource) 24 25 @classmethod 26 def generate_aws_managed_policy_arn(cls, policy_name): 27 """ 28 Method to create an ARN of AWS Owned Managed Policy. This uses the right partition name to construct 29 the ARN 30 31 :param policy_name: Name of the policy 32 :return: ARN Of the managed policy 33 """ 34 return "arn:{}:iam::aws:policy/{}".format(ArnGenerator.get_partition_name(), policy_name) 35 36 @classmethod 37 def get_partition_name(cls, region=None): 38 """ 39 Gets the name of the partition given the region name. If region name is not provided, this method will 40 use Boto3 to get name of the region where this code is running. 41 42 This implementation is borrowed from AWS CLI 43 https://github.com/aws/aws-cli/blob/1.11.139/awscli/customizations/emr/createdefaultroles.py#L59 44 45 :param region: Optional name of the region 46 :return: Partition name 47 """ 48 49 if region is None: 50 # Use Boto3 to get the region where code is running. This uses Boto's regular region resolution 51 # mechanism, starting from AWS_DEFAULT_REGION environment variable. 52 53 if ArnGenerator.BOTO_SESSION_REGION_NAME is None: 54 region = boto3.session.Session().region_name 55 else: 56 region = ArnGenerator.BOTO_SESSION_REGION_NAME 57 58 # If region is still None, then we could not find the region. This will only happen 59 # in the local context. When this is deployed, we will be able to find the region like 60 # we did before. 61 if region is None: 62 raise NoRegionFound("AWS Region cannot be found") 63 64 # setting default partition to aws, this will be overwritten by checking the region below 65 partition = "aws" 66 67 region_string = region.lower() 68 if region_string.startswith("cn-"): 69 partition = "aws-cn" 70 elif region_string.startswith("us-iso-"): 71 partition = "aws-iso" 72 elif region_string.startswith("us-isob"): 73 partition = "aws-iso-b" 74 elif region_string.startswith("us-gov"): 75 partition = "aws-us-gov" 76 77 return partition 78