From 6991ceb2e22382b2b6adcbde00ec089f11d71299 Mon Sep 17 00:00:00 2001 From: Raphael Randschau Date: Thu, 23 Mar 2017 10:21:45 +0100 Subject: [PATCH] provider/github: add repository_webhook resource (#12924) * provider/github: add repository_webhook resource `repository_webhook` can be used to manage webhooks for repositories. It is currently limited to organization repositories only. The changeset includes both documentation and tests. The tests are green: ``` make testacc TEST=./builtin/providers/github TESTARGS='-run=TestAccGithubRepositoryWebhook_basic' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/21 16:20:07 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/github -v -run=TestAccGithubRepositoryWebhook_basic -timeout 120m === RUN TestAccGithubRepositoryWebhook_basic --- PASS: TestAccGithubRepositoryWebhook_basic (5.10s) PASS ok github.com/hashicorp/terraform/builtin/providers/github 5.113s ``` * provider/github: add github_organization_webhook the `github_organization_webhook` resource is similar to the `github_repository_webhook` resource, but it manages webhooks for an organization. the tests are green: ``` make testacc TEST=./builtin/providers/github TESTARGS='-run=TestAccGithubOrganizationWebhook' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/21 17:23:33 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/github -v -run=TestAccGithubOrganizationWebhook -timeout 120m === RUN TestAccGithubOrganizationWebhook_basic --- PASS: TestAccGithubOrganizationWebhook_basic (2.09s) PASS ok github.com/hashicorp/terraform/builtin/providers/github 2.109s ``` --- builtin/providers/github/provider.go | 2 + .../resource_github_organization_webhook.go | 137 ++++++++++++ ...source_github_organization_webhook_test.go | 166 ++++++++++++++ .../resource_github_repository_webhook.go | 132 +++++++++++ ...resource_github_repository_webhook_test.go | 206 ++++++++++++++++++ .../r/organization_webhook.html.markdown | 45 ++++ .../github/r/repository_webhook.html.markdown | 61 ++++++ 7 files changed, 749 insertions(+) create mode 100644 builtin/providers/github/resource_github_organization_webhook.go create mode 100644 builtin/providers/github/resource_github_organization_webhook_test.go create mode 100644 builtin/providers/github/resource_github_repository_webhook.go create mode 100644 builtin/providers/github/resource_github_repository_webhook_test.go create mode 100644 website/source/docs/providers/github/r/organization_webhook.html.markdown create mode 100644 website/source/docs/providers/github/r/repository_webhook.html.markdown diff --git a/builtin/providers/github/provider.go b/builtin/providers/github/provider.go index 9d3c6ee7e..b3fd81d51 100644 --- a/builtin/providers/github/provider.go +++ b/builtin/providers/github/provider.go @@ -37,6 +37,8 @@ func Provider() terraform.ResourceProvider { "github_team_repository": resourceGithubTeamRepository(), "github_membership": resourceGithubMembership(), "github_repository": resourceGithubRepository(), + "github_repository_webhook": resourceGithubRepositoryWebhook(), + "github_organization_webhook": resourceGithubOrganizationWebhook(), "github_repository_collaborator": resourceGithubRepositoryCollaborator(), "github_issue_label": resourceGithubIssueLabel(), }, diff --git a/builtin/providers/github/resource_github_organization_webhook.go b/builtin/providers/github/resource_github_organization_webhook.go new file mode 100644 index 000000000..5eed3dd44 --- /dev/null +++ b/builtin/providers/github/resource_github_organization_webhook.go @@ -0,0 +1,137 @@ +package github + +import ( + "context" + "fmt" + "strconv" + + "github.com/google/go-github/github" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceGithubOrganizationWebhook() *schema.Resource { + + return &schema.Resource{ + Create: resourceGithubOrganizationWebhookCreate, + Read: resourceGithubOrganizationWebhookRead, + Update: resourceGithubOrganizationWebhookUpdate, + Delete: resourceGithubOrganizationWebhookDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateGithubOrganizationWebhookName, + }, + "events": &schema.Schema{ + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "configuration": { + Type: schema.TypeMap, + Optional: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "active": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + }, + } +} + +func validateGithubOrganizationWebhookName(v interface{}, k string) (ws []string, errors []error) { + if v.(string) != "web" { + errors = append(errors, fmt.Errorf("Github: name can only be web")) + } + return +} + +func resourceGithubOrganizationWebhookObject(d *schema.ResourceData) *github.Hook { + url := d.Get("url").(string) + active := d.Get("active").(bool) + events := []string{} + eventSet := d.Get("events").(*schema.Set) + for _, v := range eventSet.List() { + events = append(events, v.(string)) + } + name := d.Get("name").(string) + + hook := &github.Hook{ + Name: &name, + URL: &url, + Events: events, + Active: &active, + Config: d.Get("configuration").(map[string]interface{}), + } + + return hook +} + +func resourceGithubOrganizationWebhookCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hk := resourceGithubOrganizationWebhookObject(d) + + hook, _, err := client.Organizations.CreateHook(context.TODO(), meta.(*Organization).name, hk) + if err != nil { + return err + } + d.SetId(strconv.Itoa(*hook.ID)) + + return resourceGithubOrganizationWebhookRead(d, meta) +} + +func resourceGithubOrganizationWebhookRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hookID, _ := strconv.Atoi(d.Id()) + + hook, resp, err := client.Organizations.GetHook(context.TODO(), meta.(*Organization).name, hookID) + if err != nil { + if resp.StatusCode == 404 { + d.SetId("") + return nil + } + return err + } + d.Set("name", hook.Name) + d.Set("url", hook.URL) + d.Set("active", hook.Active) + d.Set("events", hook.Events) + d.Set("configuration", hook.Config) + + return nil +} + +func resourceGithubOrganizationWebhookUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hk := resourceGithubOrganizationWebhookObject(d) + hookID, err := strconv.Atoi(d.Id()) + if err != nil { + return err + } + + _, _, err = client.Organizations.EditHook(context.TODO(), meta.(*Organization).name, hookID, hk) + if err != nil { + return err + } + + return resourceGithubOrganizationWebhookRead(d, meta) +} + +func resourceGithubOrganizationWebhookDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hookID, err := strconv.Atoi(d.Id()) + if err != nil { + return err + } + + _, err = client.Organizations.DeleteHook(context.TODO(), meta.(*Organization).name, hookID) + return err +} diff --git a/builtin/providers/github/resource_github_organization_webhook_test.go b/builtin/providers/github/resource_github_organization_webhook_test.go new file mode 100644 index 000000000..6f29dbc92 --- /dev/null +++ b/builtin/providers/github/resource_github_organization_webhook_test.go @@ -0,0 +1,166 @@ +package github + +import ( + "context" + "fmt" + "reflect" + "strconv" + "strings" + "testing" + + "github.com/google/go-github/github" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccGithubOrganizationWebhook_basic(t *testing.T) { + var hook github.Hook + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGithubOrganizationWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGithubOrganizationWebhookConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubOrganizationWebhookExists("github_organization_webhook.foo", &hook), + testAccCheckGithubOrganizationWebhookAttributes(&hook, &testAccGithubOrganizationWebhookExpectedAttributes{ + Name: "web", + Events: []string{"pull_request"}, + Configuration: map[string]interface{}{ + "url": "https://google.de/webhook", + "content_type": "json", + "insecure_ssl": "1", + }, + Active: true, + }), + ), + }, + { + Config: testAccGithubOrganizationWebhookUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubOrganizationWebhookExists("github_organization_webhook.foo", &hook), + testAccCheckGithubOrganizationWebhookAttributes(&hook, &testAccGithubOrganizationWebhookExpectedAttributes{ + Name: "web", + Events: []string{"issues"}, + Configuration: map[string]interface{}{ + "url": "https://google.de/webhooks", + "content_type": "form", + "insecure_ssl": "0", + }, + Active: false, + }), + ), + }, + }, + }) +} + +func testAccCheckGithubOrganizationWebhookExists(n string, hook *github.Hook) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not Found: %s", n) + } + + hookID, _ := strconv.Atoi(rs.Primary.ID) + if hookID == 0 { + return fmt.Errorf("No repository name is set") + } + + org := testAccProvider.Meta().(*Organization) + conn := org.client + getHook, _, err := conn.Organizations.GetHook(context.TODO(), org.name, hookID) + if err != nil { + return err + } + *hook = *getHook + return nil + } +} + +type testAccGithubOrganizationWebhookExpectedAttributes struct { + Name string + Events []string + Configuration map[string]interface{} + Active bool +} + +func testAccCheckGithubOrganizationWebhookAttributes(hook *github.Hook, want *testAccGithubOrganizationWebhookExpectedAttributes) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if *hook.Name != want.Name { + return fmt.Errorf("got hook %q; want %q", *hook.Name, want.Name) + } + if *hook.Active != want.Active { + return fmt.Errorf("got hook %t; want %t", *hook.Active, want.Active) + } + if !strings.HasPrefix(*hook.URL, "https://") { + return fmt.Errorf("got http URL %q; want to start with 'https://'", *hook.URL) + } + if !reflect.DeepEqual(hook.Events, want.Events) { + return fmt.Errorf("got hook events %q; want %q", hook.Events, want.Events) + } + if !reflect.DeepEqual(hook.Config, want.Configuration) { + return fmt.Errorf("got hook configuration %q; want %q", hook.Config, want.Configuration) + } + + return nil + } +} + +func testAccCheckGithubOrganizationWebhookDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*Organization).client + orgName := testAccProvider.Meta().(*Organization).name + + for _, rs := range s.RootModule().Resources { + if rs.Type != "github_organization_webhook" { + continue + } + + id, err := strconv.Atoi(rs.Primary.ID) + if err != nil { + return err + } + + gotHook, resp, err := conn.Organizations.GetHook(context.TODO(), orgName, id) + if err == nil { + if gotHook != nil && *gotHook.ID == id { + return fmt.Errorf("Webhook still exists") + } + } + if resp.StatusCode != 404 { + return err + } + return nil + } + return nil +} + +const testAccGithubOrganizationWebhookConfig = ` +resource "github_organization_webhook" "foo" { + name = "web" + configuration { + url = "https://google.de/webhook" + content_type = "json" + insecure_ssl = true + } + + events = ["pull_request"] +} +` + +const testAccGithubOrganizationWebhookUpdateConfig = ` +resource "github_organization_webhook" "foo" { + name = "web" + configuration { + url = "https://google.de/webhooks" + content_type = "form" + insecure_ssl = false + } + active = false + + events = ["issues"] +} +` diff --git a/builtin/providers/github/resource_github_repository_webhook.go b/builtin/providers/github/resource_github_repository_webhook.go new file mode 100644 index 000000000..503e61c95 --- /dev/null +++ b/builtin/providers/github/resource_github_repository_webhook.go @@ -0,0 +1,132 @@ +package github + +import ( + "context" + "strconv" + + "github.com/google/go-github/github" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceGithubRepositoryWebhook() *schema.Resource { + return &schema.Resource{ + Create: resourceGithubRepositoryWebhookCreate, + Read: resourceGithubRepositoryWebhookRead, + Update: resourceGithubRepositoryWebhookUpdate, + Delete: resourceGithubRepositoryWebhookDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "repository": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "events": &schema.Schema{ + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "configuration": { + Type: schema.TypeMap, + Optional: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + "active": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + }, + } +} + +func resourceGithubRepositoryWebhookObject(d *schema.ResourceData) *github.Hook { + url := d.Get("url").(string) + active := d.Get("active").(bool) + events := []string{} + eventSet := d.Get("events").(*schema.Set) + for _, v := range eventSet.List() { + events = append(events, v.(string)) + } + name := d.Get("name").(string) + + hook := &github.Hook{ + Name: &name, + URL: &url, + Events: events, + Active: &active, + Config: d.Get("configuration").(map[string]interface{}), + } + + return hook +} + +func resourceGithubRepositoryWebhookCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hk := resourceGithubRepositoryWebhookObject(d) + + hook, _, err := client.Repositories.CreateHook(context.TODO(), meta.(*Organization).name, d.Get("repository").(string), hk) + if err != nil { + return err + } + d.SetId(strconv.Itoa(*hook.ID)) + + return resourceGithubRepositoryWebhookRead(d, meta) +} + +func resourceGithubRepositoryWebhookRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hookID, _ := strconv.Atoi(d.Id()) + + hook, resp, err := client.Repositories.GetHook(context.TODO(), meta.(*Organization).name, d.Get("repository").(string), hookID) + if err != nil { + if resp.StatusCode == 404 { + d.SetId("") + return nil + } + return err + } + d.Set("name", hook.Name) + d.Set("url", hook.URL) + d.Set("active", hook.Active) + d.Set("events", hook.Events) + d.Set("configuration", hook.Config) + + return nil +} + +func resourceGithubRepositoryWebhookUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hk := resourceGithubRepositoryWebhookObject(d) + hookID, err := strconv.Atoi(d.Id()) + if err != nil { + return err + } + + _, _, err = client.Repositories.EditHook(context.TODO(), meta.(*Organization).name, d.Get("repository").(string), hookID, hk) + if err != nil { + return err + } + + return resourceGithubRepositoryWebhookRead(d, meta) +} + +func resourceGithubRepositoryWebhookDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + hookID, err := strconv.Atoi(d.Id()) + if err != nil { + return err + } + + _, err = client.Repositories.DeleteHook(context.TODO(), meta.(*Organization).name, d.Get("repository").(string), hookID) + return err +} diff --git a/builtin/providers/github/resource_github_repository_webhook_test.go b/builtin/providers/github/resource_github_repository_webhook_test.go new file mode 100644 index 000000000..189cae5c3 --- /dev/null +++ b/builtin/providers/github/resource_github_repository_webhook_test.go @@ -0,0 +1,206 @@ +package github + +import ( + "context" + "fmt" + "reflect" + "strconv" + "strings" + "testing" + + "github.com/google/go-github/github" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccGithubRepositoryWebhook_basic(t *testing.T) { + randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + var hook github.Hook + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGithubRepositoryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGithubRepositoryWebhookConfig(randString), + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubRepositoryWebhookExists("github_repository_webhook.foo", fmt.Sprintf("foo-%s", randString), &hook), + testAccCheckGithubRepositoryWebhookAttributes(&hook, &testAccGithubRepositoryWebhookExpectedAttributes{ + Name: "web", + Events: []string{"pull_request"}, + Configuration: map[string]interface{}{ + "url": "https://google.de/webhook", + "content_type": "json", + "insecure_ssl": "1", + }, + Active: true, + }), + ), + }, + { + Config: testAccGithubRepositoryWebhookUpdateConfig(randString), + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubRepositoryWebhookExists("github_repository_webhook.foo", fmt.Sprintf("foo-%s", randString), &hook), + testAccCheckGithubRepositoryWebhookAttributes(&hook, &testAccGithubRepositoryWebhookExpectedAttributes{ + Name: "web", + Events: []string{"issues"}, + Configuration: map[string]interface{}{ + "url": "https://google.de/webhooks", + "content_type": "form", + "insecure_ssl": "0", + }, + Active: false, + }), + ), + }, + }, + }) +} + +func testAccCheckGithubRepositoryWebhookExists(n string, repoName string, hook *github.Hook) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not Found: %s", n) + } + + hookID, _ := strconv.Atoi(rs.Primary.ID) + if hookID == 0 { + return fmt.Errorf("No repository name is set") + } + + org := testAccProvider.Meta().(*Organization) + conn := org.client + getHook, _, err := conn.Repositories.GetHook(context.TODO(), org.name, repoName, hookID) + if err != nil { + return err + } + *hook = *getHook + return nil + } +} + +type testAccGithubRepositoryWebhookExpectedAttributes struct { + Name string + Events []string + Configuration map[string]interface{} + Active bool +} + +func testAccCheckGithubRepositoryWebhookAttributes(hook *github.Hook, want *testAccGithubRepositoryWebhookExpectedAttributes) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if *hook.Name != want.Name { + return fmt.Errorf("got hook %q; want %q", *hook.Name, want.Name) + } + if *hook.Active != want.Active { + return fmt.Errorf("got hook %t; want %t", *hook.Active, want.Active) + } + if !strings.HasPrefix(*hook.URL, "https://") { + return fmt.Errorf("got http URL %q; want to start with 'https://'", *hook.URL) + } + if !reflect.DeepEqual(hook.Events, want.Events) { + return fmt.Errorf("got hook events %q; want %q", hook.Events, want.Events) + } + if !reflect.DeepEqual(hook.Config, want.Configuration) { + return fmt.Errorf("got hook configuration %q; want %q", hook.Config, want.Configuration) + } + + return nil + } +} + +func testAccCheckGithubRepositoryWebhookDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*Organization).client + orgName := testAccProvider.Meta().(*Organization).name + + for _, rs := range s.RootModule().Resources { + if rs.Type != "github_repository_webhook" { + continue + } + + id, err := strconv.Atoi(rs.Primary.ID) + if err != nil { + return err + } + + gotHook, resp, err := conn.Repositories.GetHook(context.TODO(), orgName, rs.Primary.Attributes["repository"], id) + if err == nil { + if gotHook != nil && *gotHook.ID == id { + return fmt.Errorf("Webhook still exists") + } + } + if resp.StatusCode != 404 { + return err + } + return nil + } + return nil +} + +func testAccGithubRepositoryWebhookConfig(randString string) string { + return fmt.Sprintf(` + resource "github_repository" "foo" { + name = "foo-%s" + description = "Terraform acceptance tests" + homepage_url = "http://example.com/" + + # So that acceptance tests can be run in a github organization + # with no billing + private = false + + has_issues = true + has_wiki = true + has_downloads = true + } + + resource "github_repository_webhook" "foo" { + depends_on = ["github_repository.foo"] + repository = "foo-%s" + + name = "web" + configuration { + url = "https://google.de/webhook" + content_type = "json" + insecure_ssl = true + } + + events = ["pull_request"] + } + `, randString, randString) +} + +func testAccGithubRepositoryWebhookUpdateConfig(randString string) string { + return fmt.Sprintf(` +resource "github_repository" "foo" { + name = "foo-%s" + description = "Terraform acceptance tests" + homepage_url = "http://example.com/" + + # So that acceptance tests can be run in a github organization + # with no billing + private = false + + has_issues = true + has_wiki = true + has_downloads = true +} + +resource "github_repository_webhook" "foo" { + depends_on = ["github_repository.foo"] + repository = "foo-%s" + + name = "web" + configuration { + url = "https://google.de/webhooks" + content_type = "form" + insecure_ssl = false + } + active = false + + events = ["issues"] +} +`, randString, randString) +} diff --git a/website/source/docs/providers/github/r/organization_webhook.html.markdown b/website/source/docs/providers/github/r/organization_webhook.html.markdown new file mode 100644 index 000000000..1062d1fbc --- /dev/null +++ b/website/source/docs/providers/github/r/organization_webhook.html.markdown @@ -0,0 +1,45 @@ +--- +layout: "github" +page_title: "GitHub: github_organization_webhook" +sidebar_current: "docs-github-resource-organization-webhook" +description: |- + Creates and manages webhooks for Github organizations +--- + +# github\_organization\_webhook + +This resource allows you to create and manage webhooks for Github organization. + +## Example Usage + +``` +resource "github_organization_webhook" "foo" { + name = "web" + configuration { + url = "https://google.de/" + content_type = "form" + insecure_ssl = false + } + active = false + + events = ["issues"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The type of the webhook. See a list of [available hooks](https://api.github.com/hooks). + +* `events` - (Required) A list of events which should trigger the webhook. Defaults to `["push"]`. See a list of [available events](https://developer.github.com/v3/activity/events/types/) + +* `config` - (Required) key/value pair of configuration for this webhook. Available keys are `url`, `content_type`, `secret` and `insecure_ssl`. + +* `active` - (Optional) Indicate of the webhook should receive events. Defaults to `true`. + +## Attributes Reference + +The following additional attributes are exported: + +* `url` - URL of the webhook diff --git a/website/source/docs/providers/github/r/repository_webhook.html.markdown b/website/source/docs/providers/github/r/repository_webhook.html.markdown new file mode 100644 index 000000000..ab57d5f5c --- /dev/null +++ b/website/source/docs/providers/github/r/repository_webhook.html.markdown @@ -0,0 +1,61 @@ +--- +layout: "github" +page_title: "GitHub: github_repository_webhook" +sidebar_current: "docs-github-resource-repository-webhook" +description: |- + Creates and manages repository webhooks within Github organizations +--- + +# github\_repository\_webhook + +This resource allows you to create and manage webhooks for repositories within your +Github organization. + +This resource cannot currently be used to manage webhooks for *personal* repositories, +outside of organizations. + +## Example Usage + +``` +resource "github_repository" "repo" { + name = "foo" + description = "Terraform acceptance tests" + homepage_url = "http://example.com/" + + private = false +} + +resource "github_repository_webhook" "foo" { + repository = "${github_repository.repo.name}" + + name = "web" + configuration { + url = "https://google.de/" + content_type = "form" + insecure_ssl = false + } + active = false + + events = ["issues"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The type of the webhook. See a list of [available hooks](https://api.github.com/hooks). + +* `repository` - (Required) The repository of the webhook. + +* `events` - (Required) A list of events which should trigger the webhook. Defaults to `["push"]`. See a list of [available events](https://developer.github.com/v3/activity/events/types/) + +* `config` - (Required) key/value pair of configuration for this webhook. Available keys are `url`, `content_type`, `secret` and `insecure_ssl`. + +* `active` - (Optional) Indicate of the webhook should receive events. Defaults to `true`. + +## Attributes Reference + +The following additional attributes are exported: + +* `url` - URL of the webhook