1// Package arn provides a parser for interacting with Amazon Resource Names. 2package arn 3 4import ( 5 "errors" 6 "strings" 7) 8 9const ( 10 arnDelimiter = ":" 11 arnSections = 6 12 arnPrefix = "arn:" 13 14 // zero-indexed 15 sectionPartition = 1 16 sectionService = 2 17 sectionRegion = 3 18 sectionAccountID = 4 19 sectionResource = 5 20 21 // errors 22 invalidPrefix = "arn: invalid prefix" 23 invalidSections = "arn: not enough sections" 24) 25 26// ARN captures the individual fields of an Amazon Resource Name. 27// See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more information. 28type ARN struct { 29 // The partition that the resource is in. For standard AWS regions, the partition is "aws". If you have resources in 30 // other partitions, the partition is "aws-partitionname". For example, the partition for resources in the China 31 // (Beijing) region is "aws-cn". 32 Partition string 33 34 // The service namespace that identifies the AWS product (for example, Amazon S3, IAM, or Amazon RDS). For a list of 35 // namespaces, see 36 // http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces. 37 Service string 38 39 // The region the resource resides in. Note that the ARNs for some resources do not require a region, so this 40 // component might be omitted. 41 Region string 42 43 // The ID of the AWS account that owns the resource, without the hyphens. For example, 123456789012. Note that the 44 // ARNs for some resources don't require an account number, so this component might be omitted. 45 AccountID string 46 47 // The content of this part of the ARN varies by service. It often includes an indicator of the type of resource — 48 // for example, an IAM user or Amazon RDS database - followed by a slash (/) or a colon (:), followed by the 49 // resource name itself. Some services allows paths for resource names, as described in 50 // http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-paths. 51 Resource string 52} 53 54// Parse parses an ARN into its constituent parts. 55// 56// Some example ARNs: 57// arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment 58// arn:aws:iam::123456789012:user/David 59// arn:aws:rds:eu-west-1:123456789012:db:mysql-db 60// arn:aws:s3:::my_corporate_bucket/exampleobject.png 61func Parse(arn string) (ARN, error) { 62 if !strings.HasPrefix(arn, arnPrefix) { 63 return ARN{}, errors.New(invalidPrefix) 64 } 65 sections := strings.SplitN(arn, arnDelimiter, arnSections) 66 if len(sections) != arnSections { 67 return ARN{}, errors.New(invalidSections) 68 } 69 return ARN{ 70 Partition: sections[sectionPartition], 71 Service: sections[sectionService], 72 Region: sections[sectionRegion], 73 AccountID: sections[sectionAccountID], 74 Resource: sections[sectionResource], 75 }, nil 76} 77 78// IsARN returns whether the given string is an arn 79// by looking for whether the string starts with arn: 80func IsARN(arn string) bool { 81 return strings.HasPrefix(arn, arnPrefix) && strings.Count(arn, ":") >= arnSections-1 82} 83 84// String returns the canonical representation of the ARN 85func (arn ARN) String() string { 86 return arnPrefix + 87 arn.Partition + arnDelimiter + 88 arn.Service + arnDelimiter + 89 arn.Region + arnDelimiter + 90 arn.AccountID + arnDelimiter + 91 arn.Resource 92} 93