Skip to content

Commit

Permalink
Fixes #181 - Add support for webhook integration (#197)
Browse files Browse the repository at this point in the history
- Added supported for webhook integration
- Added headers field
  • Loading branch information
djmgit authored Dec 16, 2020
1 parent 0fce2c7 commit ae1a310
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 5 deletions.
5 changes: 3 additions & 2 deletions opsgenie/integration_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func validateResponderType(v interface{}, k string) (ws []string, errors []error
}

const (
ApiIntegrationType = "API"
EmailIntegrationType = "Email"
ApiIntegrationType = "API"
EmailIntegrationType = "Email"
WebhookIntegrationType = "Webhook"
)
100 changes: 100 additions & 0 deletions opsgenie/resource_opsgenie_api_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func resourceOpsgenieApiIntegration() *schema.Resource {
Computed: true,
Sensitive: true,
},
"webhook_url": {
Type: schema.TypeString,
Optional: true,
},
"responders": {
Type: schema.TypeList,
Optional: true,
Expand All @@ -74,11 +78,41 @@ func resourceOpsgenieApiIntegration() *schema.Resource {
},
},
},
"headers": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

func resourceOpsgenieApiIntegrationCreate(d *schema.ResourceData, meta interface{}) error {
integrationType := d.Get("type").(string)
if integrationType == WebhookIntegrationType {
return createWebhookIntegration(d, meta)
}
return createApiIntegration(d, meta)
}

func expandOpsGenieWebhookHeaders(d *schema.ResourceData) map[string]string {
input := d.Get("headers").(map[string]interface{})
output := make(map[string]string)

if input == nil {
return output
}

for k, v := range input {
output[k] = v.(string)
}

return output
}

func createApiIntegration(d *schema.ResourceData, meta interface{}) error {
client, err := integration.NewClient(meta.(*OpsgenieClient).client.Config)
if err != nil {
return err
Expand All @@ -103,6 +137,7 @@ func resourceOpsgenieApiIntegrationCreate(d *schema.ResourceData, meta interface
SuppressNotifications: &suppressNotifications,
Responders: expandOpsgenieIntegrationResponders(d),
}

if ownerTeam != "" {
createRequest.OwnerTeam = &og.OwnerTeam{
Id: ownerTeam,
Expand Down Expand Up @@ -133,6 +168,59 @@ func resourceOpsgenieApiIntegrationCreate(d *schema.ResourceData, meta interface
return resourceOpsgenieApiIntegrationRead(d, meta)
}

func createWebhookIntegration(d *schema.ResourceData, meta interface{}) error {
client, err := integration.NewClient(meta.(*OpsgenieClient).client.Config)
if err != nil {
return err
}
name := d.Get("name").(string)
allowWriteAccess := d.Get("allow_write_access").(bool)
suppressNotifications := d.Get("suppress_notifications").(bool)
ownerTeam := d.Get("owner_team_id").(string)
integrationType := d.Get("type").(string)
webhookUrl := d.Get("webhook_url").(string)
enabled := d.Get("enabled").(bool)
headers := expandOpsGenieWebhookHeaders(d)

createRequest := &integration.WebhookIntegrationRequest{
Name: name,
Type: integrationType,
AllowWriteAccess: &allowWriteAccess,
SuppressNotifications: &suppressNotifications,
Responders: expandOpsgenieIntegrationResponders(d),
WebhookUrl: webhookUrl,
Headers: headers,
}

if ownerTeam != "" {
createRequest.OwnerTeam = &og.OwnerTeam{
Id: ownerTeam,
}
}

log.Printf("[INFO] Creating OpsGenie Webhook integration '%s'", name)

result, err := client.CreateWebhook(context.Background(), createRequest)
if err != nil {
return err
}

d.SetId(result.Id)
d.Set("api_key", result.ApiKey)

if enabled {
_, err = client.Enable(context.Background(), &integration.EnableIntegrationRequest{
Id: result.Id,
})
if err != nil {
return err
}
log.Printf("[INFO] Enabled OpsGenie Webhook integration '%s'", name)
}

return resourceOpsgenieApiIntegrationRead(d, meta)
}

func resourceOpsgenieApiIntegrationRead(d *schema.ResourceData, meta interface{}) error {
client, err := integration.NewClient(meta.(*OpsgenieClient).client.Config)
if err != nil {
Expand All @@ -158,6 +246,14 @@ func resourceOpsgenieApiIntegrationRead(d *schema.ResourceData, meta interface{}
d.Set("enabled", result.Data["enabled"])
d.Set("suppress_notifications", result.Data["suppressNotifications"])

if result.Data["url"] != nil {
d.Set("webhook_url", result.Data["url"])
}

if result.Data["headers"] != nil {
d.Set("headers", result.Data["headers"])
}

return nil
}

Expand Down Expand Up @@ -187,9 +283,11 @@ func resourceOpsgenieApiIntegrationUpdate(d *schema.ResourceData, meta interface

name := d.Get("name").(string)
integrationType := d.Get("type").(string)
webhookUrl := d.Get("webhook_url").(string)
ignoreRespondersFromPayload := d.Get("ignore_responders_from_payload").(bool)
suppressNotifications := d.Get("suppress_notifications").(bool)
enabled := d.Get("enabled").(bool)
headers := expandOpsGenieWebhookHeaders(d)

if integrationType == "" {
integrationType = ApiIntegrationType
Expand All @@ -204,6 +302,8 @@ func resourceOpsgenieApiIntegrationUpdate(d *schema.ResourceData, meta interface
Responders: expandOpsgenieIntegrationResponders(d),
Enabled: &enabled,
OtherFields: userProperties,
WebhookUrl: webhookUrl,
Headers: headers,
}

log.Printf("[INFO] Updating OpsGenie api based integration '%s'", name)
Expand Down
20 changes: 17 additions & 3 deletions opsgenie/resource_opsgenie_api_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ func TestAccOpsGenieApiIntegration_complete(t *testing.T) {
randomEscalation := acctest.RandString(6)
randomIntegration := acctest.RandString(6)
randomIntegration2 := acctest.RandString(6)
randomIntegration3 := acctest.RandString(6)

config := testAccOpsGenieApiIntegration_complete(randomUsername, randomTeam, randomTeam2, randomSchedule, randomEscalation, randomIntegration, randomIntegration2)
config := testAccOpsGenieApiIntegration_complete(randomUsername, randomTeam, randomTeam2, randomSchedule, randomEscalation, randomIntegration, randomIntegration2, randomIntegration3)

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
Expand All @@ -113,6 +114,7 @@ func TestAccOpsGenieApiIntegration_complete(t *testing.T) {
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckOpsGenieApiIntegrationExists("opsgenie_api_integration.test"),
testCheckOpsGenieApiIntegrationExists("opsgenie_api_integration.test3"),
),
},
},
Expand Down Expand Up @@ -195,7 +197,7 @@ resource "opsgenie_api_integration" "test_format" {
`, randomLongName, randomName)
}

func testAccOpsGenieApiIntegration_complete(randomUsername, randomTeam, randomTeam2, randomSchedule, randomEscalation, randomIntegration, randomIntegration2 string) string {
func testAccOpsGenieApiIntegration_complete(randomUsername, randomTeam, randomTeam2, randomSchedule, randomEscalation, randomIntegration, randomIntegration2, randomIntegration3 string) string {
return fmt.Sprintf(`
resource "opsgenie_user" "test" {
username = "genietest-%[email protected]"
Expand Down Expand Up @@ -261,5 +263,17 @@ resource "opsgenie_api_integration" "test2" {
owner_team_id = "${opsgenie_team.test.id}"
enabled = true
}
`, randomUsername, randomTeam, randomTeam2, randomSchedule, randomEscalation, randomIntegration, randomIntegration2)
resource "opsgenie_api_integration" "test3" {
name = "genieintegration-webhook-%s"
owner_team_id = "${opsgenie_team.test.id}"
type = "Webhook"
enabled = true
allow_write_access = false
suppress_notifications = false
webhook_url = "https://example.com/v1"
headers = {
header = "value1"
}
}
`, randomUsername, randomTeam, randomTeam2, randomSchedule, randomEscalation, randomIntegration, randomIntegration2, randomIntegration3)
}
19 changes: 19 additions & 0 deletions website/docs/r/api_integration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ resource "opsgenie_api_integration" "example-api-integration" {
suppress_notifications = true
owner_team_id = "${opsgenie_team.team.id}"
}
resource "opsgenie_api_integration" "test3" {
name = "webhook-int"
type = "Webhook"
responders {
type = "user"
id = "${opsgenie_user.user.id}"
}
enabled = false
allow_write_access = false
suppress_notifications = true
webhook_url = "https://api.example.com/v1"
headers = {
header1 = value1
}
}
```

## Argument Reference
Expand All @@ -65,6 +82,8 @@ The following arguments are supported:

* `responders` - (Optional) User, schedule, teams or escalation names to calculate which users will receive the notifications of the alert.

* `webhook_url` - (Optional) It is required if type is `Webhook`. This is the url Opsgenie will be sending request to.

`responders` supports the following:

* `type` - (Required) The responder type.
Expand Down

0 comments on commit ae1a310

Please sign in to comment.