From 89ce6f7c831b312c389cad508beded8ab202ce35 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 30 Oct 2015 21:35:16 +0000 Subject: [PATCH 1/5] Started the work for the AWS CodeCommit Repository resource Starting to add the skeleton for the creation and update of a repository --- builtin/providers/aws/config.go | 5 + builtin/providers/aws/provider.go | 1 + .../aws/resource_aws_codecommit_repository.go | 165 ++++++++++++++++++ terraform/eval_ignore_changes.go | 3 +- 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 builtin/providers/aws/resource_aws_codecommit_repository.go diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index de1dd32efe1c..89ead4f283b1 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -17,6 +17,7 @@ import ( "github.com/aws/aws-sdk-go/service/cloudtrail" "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/aws/aws-sdk-go/service/cloudwatchlogs" + "github.com/aws/aws-sdk-go/service/codecommit" "github.com/aws/aws-sdk-go/service/codedeploy" "github.com/aws/aws-sdk-go/service/directoryservice" "github.com/aws/aws-sdk-go/service/dynamodb" @@ -78,6 +79,7 @@ type AWSClient struct { opsworksconn *opsworks.OpsWorks glacierconn *glacier.Glacier codedeployconn *codedeploy.CodeDeploy + codecommitconn *codecommit.CodeCommit } // Client configures and returns a fully initialized AWSClient @@ -213,6 +215,9 @@ func (c *Config) Client() (interface{}, error) { log.Println("[INFO] Initializing CodeDeploy Connection") client.codedeployconn = codedeploy.New(sess) + + log.Println("[INFO] Initializing CodeCommit SDK connection") + client.codecommitconn = codecommit.New(awsConfig) } if len(errs) > 0 { diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 5ed49de864ae..b5392429aaa5 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -177,6 +177,7 @@ func Provider() terraform.ResourceProvider { "aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(), "aws_codedeploy_app": resourceAwsCodeDeployApp(), "aws_codedeploy_deployment_group": resourceAwsCodeDeployDeploymentGroup(), + "aws_codecommit_repository": resourceAwsCodeCommitRepository(), "aws_customer_gateway": resourceAwsCustomerGateway(), "aws_db_instance": resourceAwsDbInstance(), "aws_db_parameter_group": resourceAwsDbParameterGroup(), diff --git a/builtin/providers/aws/resource_aws_codecommit_repository.go b/builtin/providers/aws/resource_aws_codecommit_repository.go new file mode 100644 index 000000000000..67d8ea2808d2 --- /dev/null +++ b/builtin/providers/aws/resource_aws_codecommit_repository.go @@ -0,0 +1,165 @@ +package aws + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/codecommit" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsCodeCommitRepository() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsCodeCommitRepositoryCreate, + Update: resourceAwsCodeCommitRepositoryUpdate, + Read: resourceAwsCodeCommitRepositoryRead, + Delete: resourceAwsCodeCommitRepositoryDelete, + + Schema: map[string]*schema.Schema{ + "repository_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > 100 { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than 100 characters", k)) + } + return + }, + }, + + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > 1000 { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than 1000 characters", k)) + } + return + }, + }, + + "arn": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "repository_id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "clone_url_http": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "clone_url_ssh": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "default_branch": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceAwsCodeCommitRepositoryCreate(d *schema.ResourceData, meta interface{}) error { + codecommitconn := meta.(*AWSClient).codecommitconn + + input := &codecommit.CreateRepositoryInput{ + RepositoryName: aws.String(d.Get("repository_name").(string)), + RepositoryDescription: aws.String(d.Get("description").(string)), + } + + out, err := codecommitconn.CreateRepository(input) + if err != nil { + return fmt.Errorf("Error creating CodeCommit Repository: %s", err) + } + + d.SetId(d.Get("repository_name").(string)) + d.Set("repository_id", *out.RepositoryMetadata.RepositoryId) + d.Set("arn", *out.RepositoryMetadata.Arn) + d.Set("clone_url_http", *out.RepositoryMetadata.CloneUrlHttp) + d.Set("clone_url_ssh", *out.RepositoryMetadata.CloneUrlSsh) + + return resourceAwsCodeCommitRepositoryUpdate(d, meta) +} + +func resourceAwsCodeCommitRepositoryUpdate(d *schema.ResourceData, meta interface{}) error { + codecommitconn := meta.(*AWSClient).codecommitconn + + if d.HasChange("default_branch") { + if err := resourceAwsCodeCommitUpdateDefaultBranch(codecommitconn, d); err != nil { + return err + } + } + + if d.HasChange("description") { + if err := resourceAwsCodeCommitUpdateDescription(codecommitconn, d); err != nil { + return err + } + } + + return nil +} + +func resourceAwsCodeCommitRepositoryRead(d *schema.ResourceData, meta interface{}) error { + codecommitconn := meta.(*AWSClient).codecommitconn + + input := &codecommit.GetRepositoryInput{ + RepositoryName: aws.String(d.Id()), + } + + out, err := codecommitconn.GetRepository(input) + if err != nil { + return fmt.Errorf("Error reading CodeCommit Repository: %s", err.Error()) + } + + d.Set("repository_id", *out.RepositoryMetadata.RepositoryId) + d.Set("arn", *out.RepositoryMetadata.Arn) + d.Set("clone_url_http", *out.RepositoryMetadata.CloneUrlHttp) + d.Set("clone_url_ssh", *out.RepositoryMetadata.CloneUrlSsh) + d.Set("default_branch", *out.RepositoryMetadata.DefaultBranch) + + return nil +} + +func resourceAwsCodeCommitRepositoryDelete(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func resourceAwsCodeCommitUpdateDescription(codecommitconn *codecommit.CodeCommit, d *schema.ResourceData) error { + branchInput := &codecommit.UpdateRepositoryDescriptionInput{ + RepositoryName: aws.String(d.Id()), + RepositoryDescription: aws.String(d.Get("description").(string)), + } + + _, err := codecommitconn.UpdateRepositoryDescription(branchInput) + if err != nil { + return fmt.Errorf("Error Updating Repository Description for CodeCommit Repository: %s", err.Error()) + } + + return nil +} + +func resourceAwsCodeCommitUpdateDefaultBranch(codecommitconn *codecommit.CodeCommit, d *schema.ResourceData) error { + branchInput := &codecommit.UpdateDefaultBranchInput{ + RepositoryName: aws.String(d.Id()), + DefaultBranchName: aws.String(d.Get("default_branch").(string)), + } + + _, err := codecommitconn.UpdateDefaultBranch(branchInput) + if err != nil { + return fmt.Errorf("Error Updating Default Branch for CodeCommit Repository: %s", err.Error()) + } + + return nil +} diff --git a/terraform/eval_ignore_changes.go b/terraform/eval_ignore_changes.go index 2eb2d9bb181e..cc2261313714 100644 --- a/terraform/eval_ignore_changes.go +++ b/terraform/eval_ignore_changes.go @@ -1,8 +1,9 @@ package terraform import ( - "github.com/hashicorp/terraform/config" "strings" + + "github.com/hashicorp/terraform/config" ) // EvalIgnoreChanges is an EvalNode implementation that removes diff From d9fd77c1414b6e9e09d7d293b8a6ec1e2c529119 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 18 Sep 2015 00:26:25 +0100 Subject: [PATCH 2/5] Finishing the last of the CodeCommit Repository resource. Also started to add some tests. The trouble for me right now is that CodeCommit is only in US-East-1 so I need to guard against that right now --- .../aws/resource_aws_codecommit_repository.go | 17 ++++- ...resource_aws_codecommit_repository_test.go | 76 +++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 builtin/providers/aws/resource_aws_codecommit_repository_test.go diff --git a/builtin/providers/aws/resource_aws_codecommit_repository.go b/builtin/providers/aws/resource_aws_codecommit_repository.go index 67d8ea2808d2..f1830864ef67 100644 --- a/builtin/providers/aws/resource_aws_codecommit_repository.go +++ b/builtin/providers/aws/resource_aws_codecommit_repository.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/codecommit" @@ -108,7 +109,7 @@ func resourceAwsCodeCommitRepositoryUpdate(d *schema.ResourceData, meta interfac } } - return nil + return resourceAwsCodeCommitRepositoryRead(d, meta) } func resourceAwsCodeCommitRepositoryRead(d *schema.ResourceData, meta interface{}) error { @@ -127,12 +128,24 @@ func resourceAwsCodeCommitRepositoryRead(d *schema.ResourceData, meta interface{ d.Set("arn", *out.RepositoryMetadata.Arn) d.Set("clone_url_http", *out.RepositoryMetadata.CloneUrlHttp) d.Set("clone_url_ssh", *out.RepositoryMetadata.CloneUrlSsh) - d.Set("default_branch", *out.RepositoryMetadata.DefaultBranch) + if out.RepositoryMetadata.DefaultBranch != nil { + d.Set("default_branch", *out.RepositoryMetadata.DefaultBranch) + } return nil } func resourceAwsCodeCommitRepositoryDelete(d *schema.ResourceData, meta interface{}) error { + codecommitconn := meta.(*AWSClient).codecommitconn + + log.Printf("[DEBUG] CodeCommit Delete Repository: %s", d.Id()) + _, err := codecommitconn.DeleteRepository(&codecommit.DeleteRepositoryInput{ + RepositoryName: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("Error deleting CodeCommit Repository: %s", err.Error()) + } + return nil } diff --git a/builtin/providers/aws/resource_aws_codecommit_repository_test.go b/builtin/providers/aws/resource_aws_codecommit_repository_test.go new file mode 100644 index 000000000000..7859e0d82591 --- /dev/null +++ b/builtin/providers/aws/resource_aws_codecommit_repository_test.go @@ -0,0 +1,76 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/codecommit" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSCodeCommitRepository_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodeCommitRepositoryDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCodeCommitRepository_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCodeCommitRepositoryExists("aws_codecommit_repository.test"), + ), + }, + }, + }) +} + +func testAccCheckCodeCommitRepositoryExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + codecommitconn := testAccProvider.Meta().(*AWSClient).codecommitconn + out, err := codecommitconn.GetRepository(&codecommit.GetRepositoryInput{ + RepositoryName: aws.String(rs.Primary.ID), + }) + + if err != nil { + return err + } + + if out.RepositoryMetadata.Arn == nil { + return fmt.Errorf("No CodeCommit Repository Vault Found") + } + + if *out.RepositoryMetadata.RepositoryName != rs.Primary.ID { + return fmt.Errorf("CodeCommit Repository Mismatch - existing: %q, state: %q", + *out.RepositoryMetadata.RepositoryName, rs.Primary.ID) + } + + return nil + } +} + +func testAccCheckCodeCommitRepositoryDestroy(s *terraform.State) error { + if len(s.RootModule().Resources) > 0 { + return fmt.Errorf("Expected all resources to be gone, but found: %#v", + s.RootModule().Resources) + } + + return nil +} + +const testAccCodeCommitRepository_basic = ` +resource "aws_codecommit_repository" "test" { + repository_name = "my_test_repository" + description = "This is a test description" +} +` From 2ad006ab50e24b80aa6e997105bc417ddbdd72b9 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 18 Sep 2015 09:54:14 +0100 Subject: [PATCH 3/5] Currently, AWS CodeCommit is only available in us-east-1, therefore we need to error out early if the region is anything other than this Also added a test that will show that changes get applied on subsequent runs --- .../aws/resource_aws_codecommit_repository.go | 7 ++++ ...resource_aws_codecommit_repository_test.go | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/builtin/providers/aws/resource_aws_codecommit_repository.go b/builtin/providers/aws/resource_aws_codecommit_repository.go index f1830864ef67..3f15ac409d0e 100644 --- a/builtin/providers/aws/resource_aws_codecommit_repository.go +++ b/builtin/providers/aws/resource_aws_codecommit_repository.go @@ -74,6 +74,13 @@ func resourceAwsCodeCommitRepository() *schema.Resource { func resourceAwsCodeCommitRepositoryCreate(d *schema.ResourceData, meta interface{}) error { codecommitconn := meta.(*AWSClient).codecommitconn + region := meta.(*AWSClient).region + + // This is a temporary thing - we need to ensure that CodeCommit is only being run against us-east-1 + // As this is the only place that AWS currently supports it + if region != "us-east-1" { + return fmt.Errorf("CodeCommit can only be used with US-East-1") + } input := &codecommit.CreateRepositoryInput{ RepositoryName: aws.String(d.Get("repository_name").(string)), diff --git a/builtin/providers/aws/resource_aws_codecommit_repository_test.go b/builtin/providers/aws/resource_aws_codecommit_repository_test.go index 7859e0d82591..14fcdf3211b6 100644 --- a/builtin/providers/aws/resource_aws_codecommit_repository_test.go +++ b/builtin/providers/aws/resource_aws_codecommit_repository_test.go @@ -26,6 +26,32 @@ func TestAccAWSCodeCommitRepository_basic(t *testing.T) { }) } +func TestAccAWSCodeCommitRepository_withChanges(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodeCommitRepositoryDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCodeCommitRepository_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCodeCommitRepositoryExists("aws_codecommit_repository.test"), + resource.TestCheckResourceAttr( + "aws_codecommit_repository.test", "description", "This is a test description"), + ), + }, + resource.TestStep{ + Config: testAccCodeCommitRepository_withChanges, + Check: resource.ComposeTestCheckFunc( + testAccCheckCodeCommitRepositoryExists("aws_codecommit_repository.test"), + resource.TestCheckResourceAttr( + "aws_codecommit_repository.test", "description", "This is a test description - with changes"), + ), + }, + }, + }) +} + func testAccCheckCodeCommitRepositoryExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -74,3 +100,10 @@ resource "aws_codecommit_repository" "test" { description = "This is a test description" } ` + +const testAccCodeCommitRepository_withChanges = ` +resource "aws_codecommit_repository" "test" { + repository_name = "my_test_repository" + description = "This is a test description - with changes" +} +` From 14604e432eb9b605c08d8e07c5a99eb69aa247b3 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 30 Oct 2015 21:38:13 +0000 Subject: [PATCH 4/5] Added the documentation for the CodeCommit repository --- .../aws/resource_aws_codecommit_repository.go | 2 +- .../r/code_commit_repository.html.markdown | 37 +++++++++++++++++++ website/source/layouts/aws.erb | 11 ++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 website/source/docs/providers/aws/r/code_commit_repository.html.markdown diff --git a/builtin/providers/aws/resource_aws_codecommit_repository.go b/builtin/providers/aws/resource_aws_codecommit_repository.go index 3f15ac409d0e..ac2e1b1b3d47 100644 --- a/builtin/providers/aws/resource_aws_codecommit_repository.go +++ b/builtin/providers/aws/resource_aws_codecommit_repository.go @@ -79,7 +79,7 @@ func resourceAwsCodeCommitRepositoryCreate(d *schema.ResourceData, meta interfac // This is a temporary thing - we need to ensure that CodeCommit is only being run against us-east-1 // As this is the only place that AWS currently supports it if region != "us-east-1" { - return fmt.Errorf("CodeCommit can only be used with US-East-1") + return fmt.Errorf("CodeCommit can only be used with us-east-1. You are trying to use it on %s", region) } input := &codecommit.CreateRepositoryInput{ diff --git a/website/source/docs/providers/aws/r/code_commit_repository.html.markdown b/website/source/docs/providers/aws/r/code_commit_repository.html.markdown new file mode 100644 index 000000000000..84a161f5d95d --- /dev/null +++ b/website/source/docs/providers/aws/r/code_commit_repository.html.markdown @@ -0,0 +1,37 @@ +--- +layout: "aws" +page_title: "AWS: aws_codecommit_repository" +sidebar_current: "docs-aws-resource-codecommit-repository" +description: |- + Provides a CodeCommit Repository Resource. +--- + +# aws\_codecommit\_repository + +Provides a CodeCommit Repository Resource. + +## Example Usage + +``` +resource "aws_codecommit_repository" "test" { + repository_name = "MyTestRepository" + description = "This is the Sample App Repository" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `repository_name` - (Required) The name for the repository. This needs to be less than 100 characters. +* `description` - (Optional) The description of the repository. This needs to be less than 1000 characters +* `default_branch` - (Optional) The default branch of the repository. The branch specified here needs to exist. + +## Attributes Reference + +The following attributes are exported: + +* `repository_id` - The ID of the repository +* `arn` - The ARN of the repository +* `clone_url_http` - The URL to use for cloning the repository over HTTPS. +* `clone_url_ssh` - The URL to use for cloning the repository over SSH. \ No newline at end of file diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index a12f559728ce..e9f773c29964 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -43,6 +43,16 @@ + > + CodeCommit Resources + + + > CodeDeploy Resources + > DynamoDB Resources