-
Notifications
You must be signed in to change notification settings - Fork 9.1k
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
New Resource: CloudFront Public Key #5737
Changes from 13 commits
b9aeafb
e4a216e
0975ac0
7d299ec
bc0af85
8c2d1db
32ca921
745daa8
4898652
9f50045
b83a500
e1f73b0
abfe7c4
8f80721
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/cloudfront" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsCloudFrontPublicKey() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsCloudFrontPublicKeyCreate, | ||
Read: resourceAwsCloudFrontPublicKeyRead, | ||
Update: resourceAwsCloudFrontPublicKeyUpdate, | ||
Delete: resourceAwsCloudFrontPublicKeyDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"caller_reference": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"comment": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"encoded_key": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"etag": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
ConflictsWith: []string{"name_prefix"}, | ||
ValidateFunc: validateCloudFrontPublicKeyName, | ||
}, | ||
"name_prefix": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
ConflictsWith: []string{"name"}, | ||
ValidateFunc: validateCloudFrontPublicKeyNamePrefix, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsCloudFrontPublicKeyCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudfrontconn | ||
|
||
if v, ok := d.GetOk("name"); ok { | ||
d.Set("name", v.(string)) | ||
} else if v, ok := d.GetOk("name_prefix"); ok { | ||
d.Set("name", resource.PrefixedUniqueId(v.(string))) | ||
} else { | ||
d.Set("name", resource.PrefixedUniqueId("tf-")) | ||
} | ||
|
||
request := &cloudfront.CreatePublicKeyInput{ | ||
PublicKeyConfig: expandPublicKeyConfig(d), | ||
} | ||
|
||
log.Println("[DEBUG] Create CloudFront PublicKey:", request) | ||
|
||
output, err := conn.CreatePublicKey(request) | ||
if err != nil { | ||
return fmt.Errorf("error creating CloudFront PublicKey: %s", err) | ||
} | ||
|
||
d.SetId(aws.StringValue(output.PublicKey.Id)) | ||
return resourceAwsCloudFrontPublicKeyRead(d, meta) | ||
} | ||
|
||
func resourceAwsCloudFrontPublicKeyRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudfrontconn | ||
request := &cloudfront.GetPublicKeyInput{ | ||
Id: aws.String(d.Id()), | ||
} | ||
|
||
output, err := conn.GetPublicKey(request) | ||
if err != nil { | ||
if isAWSErr(err, cloudfront.ErrCodeNoSuchPublicKey, "") { | ||
log.Printf("[WARN] No PublicKey found: %s, removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
var publicKeyConfig *cloudfront.PublicKeyConfig | ||
publicKeyConfig = output.PublicKey.PublicKeyConfig | ||
|
||
d.Set("encoded_key", publicKeyConfig.EncodedKey) | ||
d.Set("name", publicKeyConfig.Name) | ||
|
||
if publicKeyConfig.Comment != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should prefer to always call |
||
d.Set("comment", publicKeyConfig.Comment) | ||
} | ||
|
||
if publicKeyConfig.CallerReference != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here -- we should prefer to always call |
||
d.Set("caller_reference", publicKeyConfig.CallerReference) | ||
} | ||
|
||
d.Set("etag", output.ETag) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsCloudFrontPublicKeyUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudfrontconn | ||
|
||
request := &cloudfront.UpdatePublicKeyInput{ | ||
Id: aws.String(d.Id()), | ||
PublicKeyConfig: expandPublicKeyConfig(d), | ||
IfMatch: aws.String(d.Get("etag").(string)), | ||
} | ||
|
||
_, err := conn.UpdatePublicKey(request) | ||
if err != nil { | ||
return fmt.Errorf("error updating CloudFront PublicKey (%s): %s", d.Id(), err) | ||
} | ||
|
||
return resourceAwsCloudFrontPublicKeyRead(d, meta) | ||
} | ||
|
||
func resourceAwsCloudFrontPublicKeyDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudfrontconn | ||
|
||
request := &cloudfront.DeletePublicKeyInput{ | ||
Id: aws.String(d.Id()), | ||
IfMatch: aws.String(d.Get("etag").(string)), | ||
} | ||
|
||
_, err := conn.DeletePublicKey(request) | ||
if err != nil { | ||
if isAWSErr(err, cloudfront.ErrCodeNoSuchPublicKey, "") { | ||
log.Printf("[WARN] No PublicKey found: %s, removing from state", d.Id()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This log line and the |
||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func expandPublicKeyConfig(d *schema.ResourceData) *cloudfront.PublicKeyConfig { | ||
publicKeyConfig := &cloudfront.PublicKeyConfig{ | ||
EncodedKey: aws.String(d.Get("encoded_key").(string)), | ||
Name: aws.String(d.Get("name").(string)), | ||
} | ||
|
||
if v, ok := d.GetOk("comment"); ok { | ||
publicKeyConfig.Comment = aws.String(v.(string)) | ||
} | ||
|
||
if v, ok := d.GetOk("caller_reference"); ok { | ||
publicKeyConfig.CallerReference = aws.String(v.(string)) | ||
} else { | ||
publicKeyConfig.CallerReference = aws.String(time.Now().Format(time.RFC3339Nano)) | ||
} | ||
|
||
return publicKeyConfig | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/cloudfront" | ||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSCloudFrontPublicKey_basic(t *testing.T) { | ||
rInt := acctest.RandInt() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSCloudFrontPublicKeyConfig(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudFrontPublicKeyExistence("aws_cloudfront_public_key.example"), | ||
resource.TestCheckResourceAttr("aws_cloudfront_public_key.example", "comment", "test key"), | ||
resource.TestMatchResourceAttr("aws_cloudfront_public_key.example", | ||
"caller_reference", | ||
regexp.MustCompile("^20[0-9]{2}.*")), | ||
resource.TestCheckResourceAttr("aws_cloudfront_public_key.example", "name", fmt.Sprintf("tf-acc-test-%d", rInt)), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSCloudFrontPublicKey_namePrefix(t *testing.T) { | ||
startsWithPrefix := regexp.MustCompile("^tf-acc-test-") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSCloudFrontPublicKeyConfig_namePrefix(), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudFrontPublicKeyExistence("aws_cloudfront_public_key.example"), | ||
resource.TestMatchResourceAttr("aws_cloudfront_public_key.example", "name", startsWithPrefix), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSCloudFrontPublicKey_update(t *testing.T) { | ||
rInt := acctest.RandInt() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSCloudFrontPublicKeyConfig(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudFrontPublicKeyExistence("aws_cloudfront_public_key.example"), | ||
resource.TestCheckResourceAttr("aws_cloudfront_public_key.example", "comment", "test key"), | ||
), | ||
}, | ||
{ | ||
Config: testAccAWSCloudFrontPublicKeyConfigUpdate(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudFrontPublicKeyExistence("aws_cloudfront_public_key.example"), | ||
resource.TestCheckResourceAttr("aws_cloudfront_public_key.example", "comment", "test key1"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckCloudFrontPublicKeyExistence(r string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[r] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", r) | ||
} | ||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("No Id is set") | ||
} | ||
|
||
conn := testAccProvider.Meta().(*AWSClient).cloudfrontconn | ||
|
||
params := &cloudfront.GetPublicKeyInput{ | ||
Id: aws.String(rs.Primary.ID), | ||
} | ||
|
||
_, err := conn.GetPublicKey(params) | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving CloudFront PublicKey: %s", err) | ||
} | ||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckCloudFrontPublicKeyDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).cloudfrontconn | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_cloudfront_public_key" { | ||
continue | ||
} | ||
|
||
params := &cloudfront.GetPublicKeyInput{ | ||
Id: aws.String(rs.Primary.ID), | ||
} | ||
|
||
_, err := conn.GetPublicKey(params) | ||
if err == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should prefer to catch the specific error we want and ensure we return other errors, e.g. _, err := conn.GetPublicKey(params)
if isAWSErr(err, cloudfront.ErrCodeNoSuchPublicKey, "") {
continue
}
if err != nil {
return err
}
return fmt.Errorf("CloudFront PublicKey (%s) was not deleted", rs.Primary.ID) |
||
return fmt.Errorf("CloudFront PublicKey was not deleted") | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccAWSCloudFrontPublicKeyConfig(rInt int) string { | ||
return fmt.Sprintf(` | ||
resource "aws_cloudfront_public_key" "example" { | ||
comment = "test key" | ||
encoded_key = "${file("test-fixtures/cloudfront-public-key.pem")}" | ||
name = "tf-acc-test-%d" | ||
} | ||
`, rInt) | ||
} | ||
|
||
func testAccAWSCloudFrontPublicKeyConfig_namePrefix() string { | ||
return fmt.Sprintf(` | ||
resource "aws_cloudfront_public_key" "example" { | ||
comment = "test key" | ||
encoded_key = "${file("test-fixtures/cloudfront-public-key.pem")}" | ||
name_prefix = "tf-acc-test-" | ||
} | ||
`) | ||
} | ||
|
||
func testAccAWSCloudFrontPublicKeyConfigUpdate(rInt int) string { | ||
return fmt.Sprintf(` | ||
resource "aws_cloudfront_public_key" "example" { | ||
comment = "test key1" | ||
encoded_key = "${file("test-fixtures/cloudfront-public-key.pem")}" | ||
name = "tf-acc-test-%d" | ||
} | ||
`, rInt) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
-----BEGIN PUBLIC KEY----- | ||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtZCjGTEV/ttumSJBnsc2 | ||
SUzPY/wJjfNchT2mjWivg/S7HuwKp1tDHizxrXTVuZLdDKceVcSclS7otzwfmGxM | ||
Gjk2/CM2hEMThT86q76TrbH6hvGa25n8piBOkhwbwdbvmg3DRJiLR9bqw+nAPt/n | ||
1ggTcwazm1Bw7y112Ardop+buWirS3w2C6au2OdloaaLz5N1eHEHQuRpnmD+UoVR | ||
OgGeaLaU7FxKkpOps4Giu4vgjcefGlM3MrqG4FAzDMtgGZdJm4U+bldYmk0+J1yv | ||
JA0FGd9g9GhjHMT9UznxXccw7PhHQsXn4lQfOn47uO9KIq170t8FeHKEzbCMsmyA | ||
2QIDAQAB | ||
-----END PUBLIC KEY----- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declaring this variable seems extraneous and should also be protected by
nil
checks to prevent panics, e.g.