From 7bd10d7653dbeb6e41e6982ebd293f6ad58ab87c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Brod=C3=A9n?= Date: Thu, 15 Feb 2024 14:02:54 +0100 Subject: [PATCH 1/4] Bump go-api to v1.15.1 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8295669b..ef72e98c 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/cloudamqp/terraform-provider-cloudamqp go 1.20 -require github.com/84codes/go-api v1.15.0 +require github.com/84codes/go-api v1.15.1 require github.com/hashicorp/terraform-plugin-sdk v1.17.2 diff --git a/go.sum b/go.sum index d6aa51fd..c52fd484 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuW cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/84codes/go-api v1.15.0 h1:2n3ym8X6H6NZyO7Jsl75niAWWCeGHYTxGRnFohIOU2k= -github.com/84codes/go-api v1.15.0/go.mod h1:HBaMCF7NDEhvmBSjUDrQgXa4Hn0rKy6TW5LASWjjOSw= +github.com/84codes/go-api v1.15.1 h1:NnL3gzpG0JfiPtIXwmsR+QxubQmYO+QwQ7CSJYFMJ2E= +github.com/84codes/go-api v1.15.1/go.mod h1:HBaMCF7NDEhvmBSjUDrQgXa4Hn0rKy6TW5LASWjjOSw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= From 228818e051c0af712afc0111ec810c0f0a03c78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Brod=C3=A9n?= <47317658+tbroden84@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:27:05 +0100 Subject: [PATCH 2/4] Add optional responders argument for Opsgenie recipient (#258) ### WHY are these changes introduced? Request to add `responders`to OpsGenie recipient and further all alarms created with this recipient(s). [OpsGenie API-docs](https://docs.opsgenie.com/docs/alert-api#create-alert) ### WHAT is this pull request doing? - Add optional responders argument - Fixes issue when updating recipient - Updates docs. ### HOW can this pull request be tested? Create recipient, with and without responders. --- cloudamqp/resource_cloudamqp_notification.go | 149 +++++++++++++++---- docs/resources/notification.md | 36 ++++- 2 files changed, 152 insertions(+), 33 deletions(-) diff --git a/cloudamqp/resource_cloudamqp_notification.go b/cloudamqp/resource_cloudamqp_notification.go index efa9bd5f..3369e507 100644 --- a/cloudamqp/resource_cloudamqp_notification.go +++ b/cloudamqp/resource_cloudamqp_notification.go @@ -2,7 +2,7 @@ package cloudamqp import ( "errors" - "fmt" + "log" "strconv" "strings" @@ -52,22 +52,64 @@ func resourceNotification() *schema.Resource { Type: schema.TypeString, }, }, + "responders": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + Description: "Responder type, valid options are: team, user, escalation, schedule", + ValidateFunc: validateOpsgenieRespondersType(), + }, + "id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.IsUUID, + Description: "Responder ID", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Responder name", + }, + "username": { + Type: schema.TypeString, + Optional: true, + Description: "Responder username", + }, + }, + }, + Description: "Responders for OpsGenie alarms", + }, }, } } func resourceNotificationCreate(d *schema.ResourceData, meta interface{}) error { - api := meta.(*api.API) - keys := []string{"type", "value", "name", "options"} - params := make(map[string]interface{}) + var ( + api = meta.(*api.API) + keys = []string{"type", "value", "name", "options", "responders"} + params = make(map[string]interface{}) + ) + for _, k := range keys { - if v := d.Get(k); v != nil { - params[k] = v + if v := d.Get(k); v != nil && v != "" { + switch k { + case "responders": + if len(v.(*schema.Set).List()) == 0 { + continue + } + params["options"] = opsGenieRespondersParameter(v.(*schema.Set).List()) + default: + params[k] = v + } } } + log.Printf("[DEBUG] resourceNotificationCreate params %v", params) data, err := api.CreateNotification(d.Get("instance_id").(int), params) - if err != nil { return err } @@ -75,7 +117,7 @@ func resourceNotificationCreate(d *schema.ResourceData, meta interface{}) error d.SetId(data["id"].(string)) } - return resourceNotificationRead(d, meta) + return nil } func resourceNotificationRead(d *schema.ResourceData, meta interface{}) error { @@ -96,10 +138,24 @@ func resourceNotificationRead(d *schema.ResourceData, meta interface{}) error { } for k, v := range data { - if validateRecipientAttribute(k) { - if err = d.Set(k, v); err != nil { - return fmt.Errorf("error setting %s for resource %s: %s", k, d.Id(), err) + if !validateRecipientAttribute(k) { + continue + } + if v == nil || v == "" { + continue + } + + switch k { + case "options": + for key, value := range data[k].(map[string]interface{}) { + if key == "responders" { + d.Set("responders", value.([]interface{})) + } else { + d.Set(k, v) + } } + default: + d.Set(k, v) } } @@ -107,29 +163,40 @@ func resourceNotificationRead(d *schema.ResourceData, meta interface{}) error { } func resourceNotificationUpdate(d *schema.ResourceData, meta interface{}) error { - api := meta.(*api.API) - keys := []string{"type", "value", "name", "options"} - params := make(map[string]interface{}) - params["id"] = d.Id() + var ( + api = meta.(*api.API) + keys = []string{"type", "value", "name", "options", "responders"} + params = make(map[string]interface{}) + instanceID = d.Get("instance_id").(int) + recipientID = d.Id() + ) + for _, k := range keys { - if v := d.Get(k); v != nil { - params[k] = v + if v := d.Get(k); v != nil && v != "" { + switch k { + case "responders": + if len(v.(*schema.Set).List()) == 0 { + continue + } + params["options"] = opsGenieRespondersParameter(v.(*schema.Set).List()) + default: + params[k] = v + } } } - err := api.UpdateNotification(d.Get("instance_id").(int), params) - if err != nil { - return err - } - - return resourceNotificationRead(d, meta) + log.Printf("[DEBUG] resourceNotificationUpdate params %v", params) + return api.UpdateNotification(instanceID, recipientID, params) } func resourceNotificationDelete(d *schema.ResourceData, meta interface{}) error { - api := meta.(*api.API) - params := make(map[string]interface{}) - params["id"] = d.Id() - return api.DeleteNotification(d.Get("instance_id").(int), params) + var ( + api = meta.(*api.API) + instanceID = d.Get("instance_id").(int) + recipientID = d.Id() + ) + + return api.DeleteNotification(instanceID, recipientID) } func validateNotificationType() schema.SchemaValidateFunc { @@ -151,8 +218,34 @@ func validateRecipientAttribute(key string) bool { case "type", "value", "name", - "options": + "options", + "responders": return true } return false } + +func validateOpsgenieRespondersType() schema.SchemaValidateFunc { + return validation.StringInSlice([]string{ + "escalation", + "schedule", + "team", + "user", + }, true) +} + +func opsGenieRespondersParameter(responders []interface{}) map[string]interface{} { + responderParams := make(map[string]interface{}) + params := make([]map[string]interface{}, len(responders)) + for index, responder := range responders { + param := make(map[string]interface{}) + for k, v := range responder.(map[string]interface{}) { + if v != nil && v != "" { + param[k] = v + } + } + params[index] = param + } + responderParams["responders"] = params + return responderParams +} diff --git a/docs/resources/notification.md b/docs/resources/notification.md index e4fb3fe1..832c22d3 100644 --- a/docs/resources/notification.md +++ b/docs/resources/notification.md @@ -7,7 +7,9 @@ description: |- # cloudamqp_notification -This resource allows you to create and manage recipients to receive alarm notifications. There will always be a default recipient created upon instance creation. This recipient will use team email and receive notifications from default alarms. +This resource allows you to create and manage recipients to receive alarm notifications. There will +always be a default recipient created upon instance creation. This recipient will use team email and +receive notifications from default alarms. Available for all subscription plans. @@ -31,7 +33,7 @@ resource "cloudamqp_notification" "email_recipient" {
- OpsGenie recipient + OpsGenie recipient with optional responders ```hcl @@ -40,6 +42,14 @@ resource "cloudamqp_notification" "opsgenie_recipient" { type = "opsgenie" # or "opsgenie-eu" value = "" name = "OpsGenie" + responders { + type = "team" + id = "" + } + responders { + type = "user" + username = "" + } } ``` @@ -47,7 +57,7 @@ resource "cloudamqp_notification" "opsgenie_recipient" {
- Pagerduty recipient + Pagerduty recipient with optional dedup key ```hcl @@ -98,7 +108,7 @@ resource "cloudamqp_notification" "teams_recipient" {
- Victorops recipient + Victorops recipient with optional routing key (rk) ```hcl @@ -140,6 +150,20 @@ The following arguments are supported: * `value` - (Required) Integration/API key or endpoint to send the notification. * `name` - (Optional) Display name of the recipient. * `options` - (Optional) Options argument (e.g. `rk` used for VictorOps routing key). +* `responders` - (Optional) An array of reponders (only for OpsGenie). Each `responders` block +consists of the field documented below. + +___ + +The `responders` block consists of: + +* `type` - (Required) Type of responder. [`team`, `user`, `escalation`, `schedule`] +* `id` - (Optional) Identifier in UUID format +* `name` - (Optional) Name of the responder +* `username` - (Optional) Username of the responder + +Responders of type `team`, `escalation` and `schedule` can use either id or name. +While `user` can use either id or username. ## Attributes Reference @@ -174,6 +198,8 @@ This resource depends on CloudAMQP instance identifier, `cloudamqp_instance.inst ## Import -`cloudamqp_notification` can be imported using CloudAMQP internal identifier of a recipient together (CSV separated) with the instance identifier. To retrieve the identifier of a recipient, use [CloudAMQP API](https://docs.cloudamqp.com/cloudamqp_api.html#list-notification-recipients) +`cloudamqp_notification` can be imported using CloudAMQP internal identifier of a recipient together +(CSV separated) with the instance identifier. To retrieve the identifier of a recipient, use +[CloudAMQP API](https://docs.cloudamqp.com/cloudamqp_api.html#list-notification-recipients) `terraform import cloudamqp_notification.recipient ,` From 3fe101aed403f20d39d19429cc26cbbf8ba4aafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Brod=C3=A9n?= Date: Thu, 15 Feb 2024 14:30:26 +0100 Subject: [PATCH 3/4] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5a199e31..9d05f3a6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ bin/ makefile *.tar.gz dist/ +.env From 5c15fb1986cd23d1f17055e0ca5f88c8c50ac050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Brod=C3=A9n?= Date: Thu, 15 Feb 2024 14:31:16 +0100 Subject: [PATCH 4/4] Prepare for new release v1.29.4 --- CHANGELOG.md | 28 +++++++++++++++++----------- GNUmakefile | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c592532..e2bcebb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,15 @@ +## 1.29.4 (Feb 15, 2024) + +IMPROVEMENTS: + +* Added optional responders argument for OpsGenie recipient ([#258](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/258)) + ## 1.29.3 (Jan 26, 2024) IMPROVEMENTS: -* Add support for Azure monitor log integration ([#254](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/254)) -* Add support for signl4 alarms recipient ([#255](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/255)) +* Added support for Azure monitor log integration ([#254](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/254)) +* Added support for signl4 alarms recipient ([#255](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/255)) ## 1.29.2 (Jan 17, 2024) @@ -15,7 +21,7 @@ IMPROVEMENTS: BUG FIXES: -* Fix PrivateLink/Private Service Connect import ([#250](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/250)) +* Fixed PrivateLink/Private Service Connect import ([#250](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/250)) ## 1.29.0 (Dec 18, 2023) @@ -25,20 +31,20 @@ NOTES: FEATURES: -* Add resource that invoke account actions. ([#231](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/231)) -* Add new generic resource for VPC Connect ([#240](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/240)) +* Added resource that invoke account actions. ([#231](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/231)) +* Added new generic resource for VPC Connect ([#240](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/240)) - Enables GCP Private Service Connect - Handles AWS PrivateLink - Handles Azure PrivateLink -* Add configurable retries for plugin resources ([#241](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/241)) -* Add configurable retry when reading PrivateLink information ([#246](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/246)) -* Add configurable retry for GCP VPC peering ([#247](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/247)) +* Added configurable retries for plugin resources ([#241](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/241)) +* Added configurable retry when reading PrivateLink information ([#246](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/246)) +* Added configurable retry for GCP VPC peering ([#247](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/247)) IMPROVEMENTS: -* Update and clean up samples ([#235](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/235)) -* Remove default RMQ version request when version left out ([#237](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/237)) -* Handle gone VPC resource ([#238](https://github.com/cloudamqp/terraform-provider-cloudamqp/issues/238)) +* Updated and clean up samples ([#235](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/235)) +* Removed default RMQ version request when version left out ([#237](https://github.com/cloudamqp/terraform-provider-cloudamqp/pull/237)) +* Handles gone VPC resource ([#238](https://github.com/cloudamqp/terraform-provider-cloudamqp/issues/238)) ## 1.28.0 (Sep 27, 2023) diff --git a/GNUmakefile b/GNUmakefile index b4f9104e..08c325c8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,7 +1,7 @@ TEST?=$$(go list ./... |grep -v 'vendor') GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) PKG_NAME=cloudamqp -PROVIDER_VERSION = 1.29.3 +PROVIDER_VERSION = 1.29.4 default: build