Merge pull request #2210 from PeopleNet/s3-domain

Add website_domain for S3 buckets.
This commit is contained in:
Clint 2015-07-22 11:05:37 -05:00
commit 84370065d7
4 changed files with 75 additions and 14 deletions

View File

@ -155,6 +155,22 @@ func TestAccAWSRoute53Record_alias(t *testing.T) {
}) })
} }
func TestAccAWSRoute53Record_s3_alias(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRoute53RecordDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccRoute53S3AliasRecord,
Check: resource.ComposeTestCheckFunc(
testAccCheckRoute53RecordExists("aws_route53_record.alias"),
),
},
},
})
}
func TestAccAWSRoute53Record_weighted_alias(t *testing.T) { func TestAccAWSRoute53Record_weighted_alias(t *testing.T) {
resource.Test(t, resource.TestCase{ resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) }, PreCheck: func() { testAccPreCheck(t) },
@ -449,6 +465,32 @@ resource "aws_route53_record" "alias" {
} }
` `
const testAccRoute53S3AliasRecord = `
resource "aws_route53_zone" "main" {
name = "notexample.com"
}
resource "aws_s3_bucket" "website" {
bucket = "website.notexample.com"
acl = "public-read"
website {
index_document = "index.html"
}
}
resource "aws_route53_record" "alias" {
zone_id = "${aws_route53_zone.main.zone_id}"
name = "www"
type = "A"
alias {
zone_id = "${aws_s3_bucket.website.hosted_zone_id}"
name = "${aws_s3_bucket.website.website_domain}"
evaluate_target_health = true
}
}
`
const testAccRoute53WeightedElbAliasRecord = ` const testAccRoute53WeightedElbAliasRecord = `
resource "aws_route53_zone" "main" { resource "aws_route53_zone" "main" {
name = "notexample.com" name = "notexample.com"

View File

@ -77,12 +77,16 @@ func resourceAwsS3Bucket() *schema.Resource {
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"website_endpoint": &schema.Schema{ "website_endpoint": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"website_domain": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"tags": tagsSchema(), "tags": tagsSchema(),
@ -237,13 +241,18 @@ func resourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error {
} }
// Add website_endpoint as an attribute // Add website_endpoint as an attribute
endpoint, err := websiteEndpoint(s3conn, d) websiteEndpoint, err := websiteEndpoint(s3conn, d)
if err != nil { if err != nil {
return err return err
} }
if err := d.Set("website_endpoint", endpoint); err != nil { if websiteEndpoint != nil {
if err := d.Set("website_endpoint", websiteEndpoint.Endpoint); err != nil {
return err return err
} }
if err := d.Set("website_domain", websiteEndpoint.Domain); err != nil {
return err
}
}
tagSet, err := getTagSetS3(s3conn, d.Id()) tagSet, err := getTagSetS3(s3conn, d.Id())
if err != nil { if err != nil {
@ -405,11 +414,11 @@ func resourceAwsS3BucketWebsiteDelete(s3conn *s3.S3, d *schema.ResourceData) err
return nil return nil
} }
func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) { func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (*S3Website, error) {
// If the bucket doesn't have a website configuration, return an empty // If the bucket doesn't have a website configuration, return an empty
// endpoint // endpoint
if _, ok := d.GetOk("website"); !ok { if _, ok := d.GetOk("website"); !ok {
return "", nil return nil, nil
} }
bucket := d.Get("bucket").(string) bucket := d.Get("bucket").(string)
@ -421,26 +430,31 @@ func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) {
}, },
) )
if err != nil { if err != nil {
return "", err return nil, err
} }
var region string var region string
if location.LocationConstraint != nil { if location.LocationConstraint != nil {
region = *location.LocationConstraint region = *location.LocationConstraint
} }
return WebsiteEndpointUrl(bucket, region), nil return WebsiteEndpoint(bucket, region), nil
} }
func WebsiteEndpointUrl(bucket string, region string) string { func WebsiteEndpoint(bucket string, region string) *S3Website {
domain := WebsiteDomainUrl(region)
return &S3Website{Endpoint: fmt.Sprintf("%s.%s", bucket, domain), Domain: domain}
}
func WebsiteDomainUrl(region string) string {
region = normalizeRegion(region) region = normalizeRegion(region)
// Frankfurt(and probably future) regions uses different syntax for website endpoints // Frankfurt(and probably future) regions uses different syntax for website endpoints
// http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html // http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html
if region == "eu-central-1" { if region == "eu-central-1" {
return fmt.Sprintf("%s.s3-website.%s.amazonaws.com", bucket, region) return fmt.Sprintf("s3-website.%s.amazonaws.com", region)
} }
return fmt.Sprintf("%s.s3-website-%s.amazonaws.com", bucket, region) return fmt.Sprintf("s3-website-%s.amazonaws.com", region)
} }
func normalizeJson(jsonString interface{}) string { func normalizeJson(jsonString interface{}) string {
@ -465,3 +479,7 @@ func normalizeRegion(region string) string {
return region return region
} }
type S3Website struct {
Endpoint, Domain string
}

View File

@ -20,9 +20,9 @@ var websiteEndpoints = []struct {
func TestWebsiteEndpointUrl(t *testing.T) { func TestWebsiteEndpointUrl(t *testing.T) {
for _, tt := range websiteEndpoints { for _, tt := range websiteEndpoints {
s := WebsiteEndpointUrl("bucket-name", tt.in) s := WebsiteEndpoint("bucket-name", tt.in)
if s != tt.out { if s.Endpoint != tt.out {
t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s, tt.out) t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s.Endpoint, tt.out)
} }
} }
} }

View File

@ -67,3 +67,4 @@ The following attributes are exported:
* `hosted_zone_id` - The [Route 53 Hosted Zone ID](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_website_region_endpoints) for this bucket's region. * `hosted_zone_id` - The [Route 53 Hosted Zone ID](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_website_region_endpoints) for this bucket's region.
* `region` - The AWS region this bucket resides in. * `region` - The AWS region this bucket resides in.
* `website_endpoint` - The website endpoint, if the bucket is configured with a website. If not, this will be an empty string. * `website_endpoint` - The website endpoint, if the bucket is configured with a website. If not, this will be an empty string.
* `website_domain` - The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records.