Skip to content
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

aws_codebuild_webhook #38199

Merged
merged 10 commits into from
Jul 15, 2024
3 changes: 3 additions & 0 deletions .changelog/38199.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_codebuild_webhook: Add `scope_configuration` argument
```
69 changes: 68 additions & 1 deletion internal/service/codebuild/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,28 @@ func resourceWebhook() *schema.Resource {
Required: true,
ForceNew: true,
},
"scope_configuration": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
names.AttrName: {
Type: schema.TypeString,
Required: true,
},
names.AttrDomain: {
Type: schema.TypeString,
Optional: true,
ValidateDiagFunc: enum.Validate[types.WebhookScopeType](),
},
names.AttrScope: {
Type: schema.TypeString,
Required: true,
},
},
},
},
"secret": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -117,6 +139,10 @@ func resourceWebhookCreate(ctx context.Context, d *schema.ResourceData, meta int
input.FilterGroups = expandWebhookFilterGroups(v.(*schema.Set).List())
}

if v, ok := d.GetOk("scope_configuration"); ok && len(v.([]interface{})) > 0 {
input.ScopeConfiguration = expandScopeConfiguration(v.([]interface{}))
}

output, err := conn.CreateWebhook(ctx, input)

if err != nil {
Expand Down Expand Up @@ -148,9 +174,14 @@ func resourceWebhookRead(ctx context.Context, d *schema.ResourceData, meta inter

d.Set("build_type", webhook.BuildType)
d.Set("branch_filter", webhook.BranchFilter)
d.Set("filter_group", flattenWebhookFilterGroups(webhook.FilterGroups))
if err := d.Set("filter_group", flattenWebhookFilterGroups(webhook.FilterGroups)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting filter_group: %s", err)
}
d.Set("payload_url", webhook.PayloadUrl)
d.Set("project_name", d.Id())
if err := d.Set("scope_configuration", flattenScopeConfiguration(webhook.ScopeConfiguration)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting scope_configuration: %s", err)
}
d.Set("secret", d.Get("secret").(string))
d.Set(names.AttrURL, webhook.Url)

Expand Down Expand Up @@ -290,6 +321,25 @@ func expandWebhookFilter(tfMap map[string]interface{}) *types.WebhookFilter {
return apiObject
}

func expandScopeConfiguration(tfList []interface{}) *types.ScopeConfiguration {
if len(tfList) == 0 || tfList[0] == nil {
return nil
}

tfMap := tfList[0].(map[string]interface{})

apiObject := &types.ScopeConfiguration{
Name: aws.String(tfMap[names.AttrName].(string)),
Scope: types.WebhookScopeType(tfMap[names.AttrScope].(string)),
}

if v, ok := tfMap[names.AttrDomain].(string); ok && v != "" {
apiObject.Domain = aws.String(v)
}

return apiObject
}

func flattenWebhookFilterGroups(apiObjects [][]types.WebhookFilter) []interface{} {
if len(apiObjects) == 0 {
return nil
Expand Down Expand Up @@ -336,3 +386,20 @@ func flattenWebhookFilter(apiObject types.WebhookFilter) map[string]interface{}

return tfMap
}

func flattenScopeConfiguration(apiObject *types.ScopeConfiguration) []interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{
names.AttrName: apiObject.Name,
names.AttrScope: apiObject.Scope,
}

if apiObject.Domain != nil {
tfMap[names.AttrDomain] = apiObject.Domain
}

return []interface{}{tfMap}
}
91 changes: 78 additions & 13 deletions internal/service/codebuild/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ func TestAccCodeBuildWebhook_bitbucket(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccWebhookConfig_bitbucket(rName, sourceLocation),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckWebhookExists(ctx, resourceName, &webhook),
resource.TestCheckResourceAttr(resourceName, "branch_filter", ""),
resource.TestCheckResourceAttr(resourceName, "project_name", rName),
resource.TestMatchResourceAttr(resourceName, "payload_url", regexache.MustCompile(`^https://`)),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.#", acctest.Ct0),
resource.TestCheckResourceAttr(resourceName, "secret", ""),
resource.TestMatchResourceAttr(resourceName, names.AttrURL, regexache.MustCompile(`^https://`)),
),
Expand Down Expand Up @@ -80,11 +81,12 @@ func TestAccCodeBuildWebhook_gitHub(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccWebhookConfig_gitHub(rName),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckWebhookExists(ctx, resourceName, &webhook),
resource.TestCheckResourceAttr(resourceName, "branch_filter", ""),
resource.TestCheckResourceAttr(resourceName, "project_name", rName),
resource.TestMatchResourceAttr(resourceName, "payload_url", regexache.MustCompile(`^https://`)),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.#", acctest.Ct0),
resource.TestCheckResourceAttr(resourceName, "secret", ""),
resource.TestMatchResourceAttr(resourceName, names.AttrURL, regexache.MustCompile(`^https://`)),
),
Expand Down Expand Up @@ -117,11 +119,12 @@ func TestAccCodeBuildWebhook_gitHubEnterprise(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccWebhookConfig_gitHubEnterprise(rName, "dev"),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckWebhookExists(ctx, resourceName, &webhook),
resource.TestCheckResourceAttr(resourceName, "branch_filter", "dev"),
resource.TestCheckResourceAttr(resourceName, "project_name", rName),
resource.TestMatchResourceAttr(resourceName, "payload_url", regexache.MustCompile(`^https://`)),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.#", acctest.Ct0),
resource.TestMatchResourceAttr(resourceName, "secret", regexache.MustCompile(`.+`)),
resource.TestCheckResourceAttr(resourceName, names.AttrURL, ""),
),
Expand All @@ -134,11 +137,12 @@ func TestAccCodeBuildWebhook_gitHubEnterprise(t *testing.T) {
},
{
Config: testAccWebhookConfig_gitHubEnterprise(rName, "master"),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckWebhookExists(ctx, resourceName, &webhook),
resource.TestCheckResourceAttr(resourceName, "branch_filter", "master"),
resource.TestCheckResourceAttr(resourceName, "project_name", rName),
resource.TestMatchResourceAttr(resourceName, "payload_url", regexache.MustCompile(`^https://`)),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.#", acctest.Ct0),
resource.TestMatchResourceAttr(resourceName, "secret", regexache.MustCompile(`.+`)),
resource.TestCheckResourceAttr(resourceName, names.AttrURL, ""),
),
Expand Down Expand Up @@ -200,6 +204,41 @@ func TestAccCodeBuildWebhook_buildType(t *testing.T) {
})
}

func TestAccCodeBuildWebhook_scopeConfiguration(t *testing.T) {
ctx := acctest.Context(t)
var webhook types.Webhook
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_codebuild_webhook.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
testAccPreCheck(ctx, t)
testAccPreCheckSourceCredentialsForServerType(ctx, t, types.ServerTypeGithub)
},
ErrorCheck: acctest.ErrorCheck(t, names.CodeBuildServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckWebhookDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccWebhookConfig_scopeConfiguration(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWebhookExists(ctx, resourceName, &webhook),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.0.name", rName),
resource.TestCheckResourceAttr(resourceName, "scope_configuration.0.scope", "GITHUB_GLOBAL"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"secret"},
},
},
})
}

func TestAccCodeBuildWebhook_branchFilter(t *testing.T) {
ctx := acctest.Context(t)
var webhook types.Webhook
Expand Down Expand Up @@ -409,19 +448,15 @@ func testAccCheckWebhookExists(ctx context.Context, n string, v *types.Webhook)
}

func testAccWebhookConfig_bitbucket(rName, sourceLocation string) string {
return acctest.ConfigCompose(
testAccProjectConfig_sourceTypeBitbucket(rName, sourceLocation),
`
return acctest.ConfigCompose(testAccProjectConfig_sourceTypeBitbucket(rName, sourceLocation), `
resource "aws_codebuild_webhook" "test" {
project_name = aws_codebuild_project.test.name
}
`)
}

func testAccWebhookConfig_gitHub(rName string) string {
return acctest.ConfigCompose(
testAccProjectConfig_basic(rName),
`
return acctest.ConfigCompose(testAccProjectConfig_basic(rName), `
resource "aws_codebuild_webhook" "test" {
project_name = aws_codebuild_project.test.name
}
Expand Down Expand Up @@ -476,9 +511,7 @@ resource "aws_codebuild_webhook" "test" {
}

func testAccWebhookConfig_filterGroup(rName string) string {
return acctest.ConfigCompose(
testAccProjectConfig_basic(rName),
`
return acctest.ConfigCompose(testAccProjectConfig_basic(rName), `
resource "aws_codebuild_webhook" "test" {
project_name = aws_codebuild_project.test.name

Expand All @@ -504,3 +537,35 @@ resource "aws_codebuild_webhook" "test" {
}
`)
}

func testAccWebhookConfig_scopeConfiguration(rName string) string {
return acctest.ConfigCompose(testAccProjectConfig_baseServiceRole(rName), fmt.Sprintf(`
resource "aws_codebuild_project" "test" {
name = %[1]q
service_role = aws_iam_role.test.arn

artifacts {
type = "NO_ARTIFACTS"
}

environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "2"
type = "LINUX_CONTAINER"
}

source {
location = "CODEBUILD_DEFAULT_WEBHOOK_SOURCE_LOCATION"
type = "GITHUB"
}
}

resource "aws_codebuild_webhook" "test" {
project_name = aws_codebuild_project.test.name
scope_configuration {
name = %[1]q
scope = "GITHUB_GLOBAL"
}
}
`, rName))
}
7 changes: 7 additions & 0 deletions website/docs/r/codebuild_webhook.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ This resource supports the following arguments:
* `build_type` - (Optional) The type of build this webhook will trigger. Valid values for this parameter are: `BUILD`, `BUILD_BATCH`.
* `branch_filter` - (Optional) A regular expression used to determine which branches get built. Default is all branches are built. We recommend using `filter_group` over `branch_filter`.
* `filter_group` - (Optional) Information about the webhook's trigger. Filter group blocks are documented below.
* `scope_configuration` - (Optional) Scope configuration for global or organization webhooks. Scope configuration blocks are documented below.

`filter_group` supports the following:

Expand All @@ -83,6 +84,12 @@ This resource supports the following arguments:
* `pattern` - (Required) For a filter that uses `EVENT` type, a comma-separated string that specifies one event: `PUSH`, `PULL_REQUEST_CREATED`, `PULL_REQUEST_UPDATED`, `PULL_REQUEST_REOPENED`. `PULL_REQUEST_MERGED`, `WORKFLOW_JOB_QUEUED` works with GitHub & GitHub Enterprise only. For a filter that uses any of the other filter types, a regular expression.
* `exclude_matched_pattern` - (Optional) If set to `true`, the specified filter does *not* trigger a build. Defaults to `false`.

`scope_configuration` supports the following:

* `name` - (Required) The name of either the enterprise or organization.
* `scope` - (Required) The type of scope for a GitHub webhook. Valid values for this parameter are: `GITHUB_ORGANIZATION`, `GITHUB_GLOBAL`.
* `domain` - (Optional) The domain of the GitHub Enterprise organization. Required if your project's source type is GITHUB_ENTERPRISE.

## Attribute Reference

This resource exports the following attributes in addition to the arguments above:
Expand Down
Loading