Skip to content

Commit

Permalink
Add data source organization webhooks and repository webhooks (#1300)
Browse files Browse the repository at this point in the history
* Add data source organization webhooks and repository webhooks

* Add doc

* Fix id

* Add link in the main doc
  • Loading branch information
bpaquet authored Oct 13, 2022
1 parent 0080e4a commit ad2193c
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 0 deletions.
76 changes: 76 additions & 0 deletions github/data_source_github_organization_webhooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package github

import (
"context"

"github.com/google/go-github/v47/github"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func dataSourceGithubOrganizationWebhooks() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubOrganizationWebhooksRead,

Schema: map[string]*schema.Schema{
"webhooks": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"url": {
Type: schema.TypeString,
Computed: true,
},
"active": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
},
}
}

func dataSourceGithubOrganizationWebhooksRead(d *schema.ResourceData, meta interface{}) error {
owner := meta.(*Owner).name

client := meta.(*Owner).v3client
ctx := context.Background()

options := &github.ListOptions{
PerPage: 100,
}

results := make([]map[string]interface{}, 0)
for {
hooks, resp, err := client.Organizations.ListHooks(ctx, owner, options)
if err != nil {
return err
}

results = append(results, flattenGitHubWebhooks(hooks)...)
if resp.NextPage == 0 {
break
}

options.Page = resp.NextPage
}

d.SetId(owner)
d.Set("webhooks", results)

return nil
}
65 changes: 65 additions & 0 deletions github/data_source_github_organization_webhooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package github

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccGithubOrganizationWebhooksDataSource(t *testing.T) {
t.Run("manages organization webhooks", func(t *testing.T) {
config := `
resource "github_organization_webhook" "test" {
configuration {
url = "https://google.de/webhook"
content_type = "json"
insecure_ssl = true
}
events = ["pull_request"]
}
`

config2 := config + `
data "github_organization_webhooks" "test" {}
`

const resourceName = "data.github_organization_webhooks.test"
check := resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "webhooks.#", "1"),
resource.TestCheckResourceAttr(resourceName, "webhooks.0.name", "web"),
resource.TestCheckResourceAttr(resourceName, "webhooks.0.url", "https://google.de/webhook"),
resource.TestCheckResourceAttr(resourceName, "webhooks.0.active", "true"),
resource.TestCheckResourceAttrSet(resourceName, "webhooks.0.id"),
)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, mode) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(),
},
{
Config: config2,
Check: check,
},
},
})
}

t.Run("with an anonymous account", func(t *testing.T) {
t.Skip("anonymous account not supported for this operation")
})

t.Run("with an individual account", func(t *testing.T) {
testCase(t, individual)
})

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})
})
}
106 changes: 106 additions & 0 deletions github/data_source_github_repository_webhooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package github

import (
"context"
"fmt"

"github.com/google/go-github/v47/github"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func dataSourceGithubRepositoryWebhooks() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubRepositoryWebhooksRead,

Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
},
"webhooks": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"url": {
Type: schema.TypeString,
Computed: true,
},
"active": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
},
}
}

func dataSourceGithubRepositoryWebhooksRead(d *schema.ResourceData, meta interface{}) error {
repository := d.Get("repository").(string)
owner := meta.(*Owner).name

client := meta.(*Owner).v3client
ctx := context.Background()

options := &github.ListOptions{
PerPage: 100,
}

results := make([]map[string]interface{}, 0)
for {
hooks, resp, err := client.Repositories.ListHooks(ctx, owner, repository, options)
if err != nil {
return err
}

results = append(results, flattenGitHubWebhooks(hooks)...)

if resp.NextPage == 0 {
break
}

options.Page = resp.NextPage
}

d.SetId(fmt.Sprintf("%s/%s", owner, repository))
d.Set("repository", repository)
d.Set("webhooks", results)

return nil
}

func flattenGitHubWebhooks(hooks []*github.Hook) []map[string]interface{} {
results := make([]map[string]interface{}, 0)

if hooks == nil {
return results
}

for _, hook := range hooks {
result := make(map[string]interface{})

result["id"] = hook.ID
result["type"] = hook.Type
result["name"] = hook.Name
result["url"] = hook.Config["url"]
result["active"] = hook.Active

results = append(results, result)
}

return results
}
78 changes: 78 additions & 0 deletions github/data_source_github_repository_webhooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package github

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccGithubRepositoryWebhooksDataSource(t *testing.T) {
t.Run("manages repository webhooks", func(t *testing.T) {
repoName := fmt.Sprintf("tf-acc-test-webhooks-%s", acctest.RandString(5))

config := fmt.Sprintf(`
resource "github_repository" "test" {
name = "%s"
auto_init = true
}
resource "github_repository_webhook" "test" {
repository = github_repository.test.name
configuration {
url = "https://google.de/webhook"
content_type = "json"
insecure_ssl = true
}
events = ["pull_request"]
}
`, repoName)

config2 := config + `
data "github_repository_webhooks" "test" {
repository = github_repository.test.name
}
`

const resourceName = "data.github_repository_webhooks.test"
check := resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "webhooks.#", "1"),
resource.TestCheckResourceAttr(resourceName, "webhooks.0.name", "web"),
resource.TestCheckResourceAttr(resourceName, "webhooks.0.url", "https://google.de/webhook"),
resource.TestCheckResourceAttr(resourceName, "webhooks.0.active", "true"),
resource.TestCheckResourceAttrSet(resourceName, "webhooks.0.id"),
)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, mode) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(),
},
{
Config: config2,
Check: check,
},
},
})
}

t.Run("with an anonymous account", func(t *testing.T) {
t.Skip("anonymous account not supported for this operation")
})

t.Run("with an individual account", func(t *testing.T) {
testCase(t, individual)
})

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})
})
}
2 changes: 2 additions & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ func Provider() terraform.ResourceProvider {
"github_organization_ip_allow_list": dataSourceGithubOrganizationIpAllowList(),
"github_organization_team_sync_groups": dataSourceGithubOrganizationTeamSyncGroups(),
"github_organization_teams": dataSourceGithubOrganizationTeams(),
"github_organization_webhooks": dataSourceGithubOrganizationWebhooks(),
"github_ref": dataSourceGithubRef(),
"github_release": dataSourceGithubRelease(),
"github_repositories": dataSourceGithubRepositories(),
Expand All @@ -161,6 +162,7 @@ func Provider() terraform.ResourceProvider {
"github_repository_pull_request": dataSourceGithubRepositoryPullRequest(),
"github_repository_pull_requests": dataSourceGithubRepositoryPullRequests(),
"github_repository_teams": dataSourceGithubRepositoryTeams(),
"github_repository_webhooks": dataSourceGithubRepositoryWebhooks(),
"github_team": dataSourceGithubTeam(),
"github_tree": dataSourceGithubTree(),
"github_user": dataSourceGithubUser(),
Expand Down
31 changes: 31 additions & 0 deletions website/docs/d/organization_webhooks.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
layout: "github"
page_title: "GitHub: github_organization_webhooks"
description: |-
Get information on all Github webhooks of the organization.
---

# github\_organization\_webhooks

Use this data source to retrieve all webhooks of the organization.

## Example Usage

To retrieve *all* webhooks of the organization:

```hcl
data "github_organization_webhooks" "all" {}
```

## Attributes Reference

* `webhooks` - An Array of GitHub Webhooks. Each `webhook` block consists of the fields documented below.
___

The `webhook` block consists of:

* `id` - the ID of the webhook.
* `type` - the type of the webhook.
* `name` - the name of the webhook.
* `url` - the url of the webhook.
* `active` - `true` if the webhook is active.
Loading

0 comments on commit ad2193c

Please sign in to comment.