-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13467 from carthewd/master
CodeCommit approval rule template association
- Loading branch information
Showing
6 changed files
with
412 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-resource | ||
aws_codecommit_approval_rule_template_association | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
internal/service/codecommit/approval_rule_template_association.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package codecommit | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/codecommit" | ||
"github.com/hashicorp/aws-sdk-go-base/tfawserr" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
"github.com/hashicorp/terraform-provider-aws/internal/conns" | ||
"github.com/hashicorp/terraform-provider-aws/internal/tfresource" | ||
) | ||
|
||
func ResourceApprovalRuleTemplateAssociation() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceApprovalRuleTemplateAssociationCreate, | ||
Read: resourceApprovalRuleTemplateAssociationRead, | ||
Delete: resourceApprovalRuleTemplateAssociationDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"approval_rule_template_name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringLenBetween(1, 100), | ||
}, | ||
"repository_name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.All( | ||
validation.StringLenBetween(1, 100), | ||
validation.StringMatch(regexp.MustCompile(`[\w\.-]+`), ""), | ||
), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceApprovalRuleTemplateAssociationCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*conns.AWSClient).CodeCommitConn | ||
|
||
approvalRuleTemplateName := d.Get("approval_rule_template_name").(string) | ||
repositoryName := d.Get("repository_name").(string) | ||
|
||
input := &codecommit.AssociateApprovalRuleTemplateWithRepositoryInput{ | ||
ApprovalRuleTemplateName: aws.String(approvalRuleTemplateName), | ||
RepositoryName: aws.String(repositoryName), | ||
} | ||
|
||
_, err := conn.AssociateApprovalRuleTemplateWithRepository(input) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error associating CodeCommit Approval Rule Template (%s) with repository (%s): %w", approvalRuleTemplateName, repositoryName, err) | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%s,%s", approvalRuleTemplateName, repositoryName)) | ||
|
||
return resourceApprovalRuleTemplateAssociationRead(d, meta) | ||
} | ||
|
||
func resourceApprovalRuleTemplateAssociationRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*conns.AWSClient).CodeCommitConn | ||
|
||
approvalRuleTemplateName, repositoryName, err := ApprovalRuleTemplateAssociationParseID(d.Id()) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
err = FindApprovalRuleTemplateAssociation(conn, approvalRuleTemplateName, repositoryName) | ||
|
||
if !d.IsNewResource() && tfresource.NotFound(err) { | ||
log.Printf("[WARN] CodeCommit Approval Rule Template Association (%s) not found, removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading CodeCommit Approval Rule Template Association (%s): %w", d.Id(), err) | ||
} | ||
|
||
d.Set("approval_rule_template_name", approvalRuleTemplateName) | ||
d.Set("repository_name", repositoryName) | ||
|
||
return nil | ||
} | ||
|
||
func resourceApprovalRuleTemplateAssociationDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*conns.AWSClient).CodeCommitConn | ||
|
||
approvalRuleTemplateName, repositoryName, err := ApprovalRuleTemplateAssociationParseID(d.Id()) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
input := &codecommit.DisassociateApprovalRuleTemplateFromRepositoryInput{ | ||
ApprovalRuleTemplateName: aws.String(approvalRuleTemplateName), | ||
RepositoryName: aws.String(repositoryName), | ||
} | ||
|
||
_, err = conn.DisassociateApprovalRuleTemplateFromRepository(input) | ||
|
||
if tfawserr.ErrCodeEquals(err, codecommit.ErrCodeApprovalRuleTemplateDoesNotExistException, codecommit.ErrCodeRepositoryDoesNotExistException) { | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error disassociating CodeCommit Approval Rule Template (%s) from repository (%s): %w", approvalRuleTemplateName, repositoryName, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func ApprovalRuleTemplateAssociationParseID(id string) (string, string, error) { | ||
parts := strings.SplitN(id, ",", 2) | ||
if len(parts) != 2 || parts[0] == "" || parts[1] == "" { | ||
return "", "", fmt.Errorf("unexpected format of ID (%s), expected APPROVAL_RULE_TEMPLATE_NAME,REPOSITORY_NAME", id) | ||
} | ||
|
||
return parts[0], parts[1], nil | ||
} |
180 changes: 180 additions & 0 deletions
180
internal/service/codecommit/approval_rule_template_association_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
package codecommit_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/codecommit" | ||
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
"github.com/hashicorp/terraform-provider-aws/internal/acctest" | ||
"github.com/hashicorp/terraform-provider-aws/internal/conns" | ||
tfcodecommit "github.com/hashicorp/terraform-provider-aws/internal/service/codecommit" | ||
"github.com/hashicorp/terraform-provider-aws/internal/tfresource" | ||
) | ||
|
||
func TestAccCodeCommitApprovalRuleTemplateAssociation_basic(t *testing.T) { | ||
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) | ||
resourceName := "aws_codecommit_approval_rule_template_association.test" | ||
repoResourceName := "aws_codecommit_repository.test" | ||
templateResourceName := "aws_codecommit_approval_rule_template.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { acctest.PreCheck(t) }, | ||
ErrorCheck: acctest.ErrorCheck(t, codecommit.EndpointsID), | ||
Providers: acctest.Providers, | ||
CheckDestroy: testAccCheckCodeCommitApprovalRuleTemplateAssociationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCodeCommitApprovalRuleTemplateAssociation_basic(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCodeCommitApprovalRuleTemplateAssociationExists(resourceName), | ||
resource.TestCheckResourceAttrPair(resourceName, "approval_rule_template_name", templateResourceName, "name"), | ||
resource.TestCheckResourceAttrPair(resourceName, "repository_name", repoResourceName, "repository_name"), | ||
), | ||
}, | ||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccCodeCommitApprovalRuleTemplateAssociation_disappears(t *testing.T) { | ||
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) | ||
resourceName := "aws_codecommit_approval_rule_template_association.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { acctest.PreCheck(t) }, | ||
ErrorCheck: acctest.ErrorCheck(t, codecommit.EndpointsID), | ||
Providers: acctest.Providers, | ||
CheckDestroy: testAccCheckCodeCommitApprovalRuleTemplateAssociationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCodeCommitApprovalRuleTemplateAssociation_basic(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCodeCommitApprovalRuleTemplateAssociationExists(resourceName), | ||
acctest.CheckResourceDisappears(acctest.Provider, tfcodecommit.ResourceApprovalRuleTemplateAssociation(), resourceName), | ||
), | ||
ExpectNonEmptyPlan: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccCodeCommitApprovalRuleTemplateAssociation_Disappears_repository(t *testing.T) { | ||
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) | ||
repoResourceName := "aws_codecommit_repository.test" | ||
resourceName := "aws_codecommit_approval_rule_template_association.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { acctest.PreCheck(t) }, | ||
ErrorCheck: acctest.ErrorCheck(t, codecommit.EndpointsID), | ||
Providers: acctest.Providers, | ||
CheckDestroy: testAccCheckCodeCommitApprovalRuleTemplateAssociationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCodeCommitApprovalRuleTemplateAssociation_basic(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCodeCommitApprovalRuleTemplateAssociationExists(resourceName), | ||
acctest.CheckResourceDisappears(acctest.Provider, tfcodecommit.ResourceRepository(), repoResourceName), | ||
), | ||
ExpectNonEmptyPlan: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckCodeCommitApprovalRuleTemplateAssociationExists(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") | ||
} | ||
|
||
conn := acctest.Provider.Meta().(*conns.AWSClient).CodeCommitConn | ||
|
||
approvalTemplateName, repositoryName, err := tfcodecommit.ApprovalRuleTemplateAssociationParseID(rs.Primary.ID) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
err = tfcodecommit.FindApprovalRuleTemplateAssociation(conn, approvalTemplateName, repositoryName) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckCodeCommitApprovalRuleTemplateAssociationDestroy(s *terraform.State) error { | ||
conn := acctest.Provider.Meta().(*conns.AWSClient).CodeCommitConn | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_codecommit_approval_rule_template_association" { | ||
continue | ||
} | ||
|
||
approvalTemplateName, repositoryName, err := tfcodecommit.ApprovalRuleTemplateAssociationParseID(rs.Primary.ID) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
err = tfcodecommit.FindApprovalRuleTemplateAssociation(conn, approvalTemplateName, repositoryName) | ||
|
||
if tfresource.NotFound(err) { | ||
continue | ||
} | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return fmt.Errorf("CodeCommit Approval Rule Template Association %s still exists", rs.Primary.ID) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCodeCommitApprovalRuleTemplateAssociation_basic(rName string) string { | ||
return fmt.Sprintf(` | ||
data "aws_caller_identity" "current" {} | ||
data "aws_partition" "current" {} | ||
resource "aws_codecommit_approval_rule_template" "test" { | ||
name = %[1]q | ||
content = <<EOF | ||
{ | ||
"Version": "2018-11-08", | ||
"DestinationReferences": ["refs/heads/master"], | ||
"Statements": [{ | ||
"Type": "Approvers", | ||
"NumberOfApprovalsNeeded": 2, | ||
"ApprovalPoolMembers": ["arn:${data.aws_partition.current.partition}:sts::${data.aws_caller_identity.current.account_id}:assumed-role/CodeCommitReview/*"]}] | ||
} | ||
EOF | ||
} | ||
resource "aws_codecommit_repository" "test" { | ||
repository_name = %[1]q | ||
} | ||
resource "aws_codecommit_approval_rule_template_association" "test" { | ||
approval_rule_template_name = aws_codecommit_approval_rule_template.test.name | ||
repository_name = aws_codecommit_repository.test.repository_name | ||
} | ||
`, rName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package codecommit | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/codecommit" | ||
"github.com/hashicorp/aws-sdk-go-base/tfawserr" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
) | ||
|
||
// FindApprovalRuleTemplateAssociation validates that an approval rule template has the named associated repository | ||
func FindApprovalRuleTemplateAssociation(conn *codecommit.CodeCommit, approvalRuleTemplateName, repositoryName string) error { | ||
input := &codecommit.ListRepositoriesForApprovalRuleTemplateInput{ | ||
ApprovalRuleTemplateName: aws.String(approvalRuleTemplateName), | ||
} | ||
|
||
found := false | ||
|
||
err := conn.ListRepositoriesForApprovalRuleTemplatePages(input, func(page *codecommit.ListRepositoriesForApprovalRuleTemplateOutput, lastPage bool) bool { | ||
if page == nil { | ||
return !lastPage | ||
} | ||
|
||
for _, repoName := range page.RepositoryNames { | ||
if aws.StringValue(repoName) == repositoryName { | ||
found = true | ||
return false | ||
} | ||
} | ||
|
||
return !lastPage | ||
}) | ||
|
||
if tfawserr.ErrCodeEquals(err, codecommit.ErrCodeApprovalRuleTemplateDoesNotExistException) { | ||
return &resource.NotFoundError{ | ||
LastError: err, | ||
LastRequest: input, | ||
} | ||
} | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
if !found { | ||
return &resource.NotFoundError{ | ||
Message: fmt.Sprintf("No approval rule template (%q) associated with repository (%q)", approvalRuleTemplateName, repositoryName), | ||
LastRequest: input, | ||
} | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.