Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2452 from modular-magician/codegen-pr-896
Browse files Browse the repository at this point in the history
Stackdriver notification channel
chrisst authored and nat-henderson committed Dec 5, 2018

Verified

This commit was signed with the committer’s verified signature.
Ladicek Ladislav Thon
1 parent 3718ba6 commit a10491a
Showing 5 changed files with 619 additions and 2 deletions.
5 changes: 3 additions & 2 deletions google/provider_monitoring_gen.go
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ package google
import "github.com/hashicorp/terraform/helper/schema"

var GeneratedMonitoringResourcesMap = map[string]*schema.Resource{
"google_monitoring_alert_policy": resourceMonitoringAlertPolicy(),
"google_monitoring_group": resourceMonitoringGroup(),
"google_monitoring_alert_policy": resourceMonitoringAlertPolicy(),
"google_monitoring_group": resourceMonitoringGroup(),
"google_monitoring_notification_channel": resourceMonitoringNotificationChannel(),
}
376 changes: 376 additions & 0 deletions google/resource_monitoring_notification_channel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,376 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
"fmt"
"log"
"reflect"

"github.com/hashicorp/terraform/helper/schema"
)

func resourceMonitoringNotificationChannel() *schema.Resource {
return &schema.Resource{
Create: resourceMonitoringNotificationChannelCreate,
Read: resourceMonitoringNotificationChannelRead,
Update: resourceMonitoringNotificationChannelUpdate,
Delete: resourceMonitoringNotificationChannelDelete,

Importer: &schema.ResourceImporter{
State: resourceMonitoringNotificationChannelImport,
},

Schema: map[string]*schema.Schema{
"display_name": {
Type: schema.TypeString,
Required: true,
},
"type": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"labels": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"user_labels": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"verification_status": {
Type: schema.TypeString,
Computed: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
}

func resourceMonitoringNotificationChannelCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})
labelsProp, err := expandMonitoringNotificationChannelLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
typeProp, err := expandMonitoringNotificationChannelType(d.Get("type"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("type"); !isEmptyValue(reflect.ValueOf(typeProp)) && (ok || !reflect.DeepEqual(v, typeProp)) {
obj["type"] = typeProp
}
userLabelsProp, err := expandMonitoringNotificationChannelUserLabels(d.Get("user_labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("user_labels"); !isEmptyValue(reflect.ValueOf(userLabelsProp)) && (ok || !reflect.DeepEqual(v, userLabelsProp)) {
obj["userLabels"] = userLabelsProp
}
descriptionProp, err := expandMonitoringNotificationChannelDescription(d.Get("description"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
displayNameProp, err := expandMonitoringNotificationChannelDisplayName(d.Get("display_name"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) {
obj["displayName"] = displayNameProp
}
enabledProp, err := expandMonitoringNotificationChannelEnabled(d.Get("enabled"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) {
obj["enabled"] = enabledProp
}

lockName, err := replaceVars(d, config, "stackdriver/notifications/{{project}}")
if err != nil {
return err
}
mutexKV.Lock(lockName)
defer mutexKV.Unlock(lockName)

url, err := replaceVars(d, config, "https://monitoring.googleapis.com/v3/projects/{{project}}/notificationChannels")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new NotificationChannel: %#v", obj)
res, err := sendRequest(config, "POST", url, obj)
if err != nil {
return fmt.Errorf("Error creating NotificationChannel: %s", err)
}

// Store the ID now
id, err := replaceVars(d, config, "{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

log.Printf("[DEBUG] Finished creating NotificationChannel %q: %#v", d.Id(), res)

// `name` is autogenerated from the api so needs to be set post-create
name, ok := res["name"]
if !ok {
return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
}
d.Set("name", name.(string))
d.SetId(name.(string))

return resourceMonitoringNotificationChannelRead(d, meta)
}

func resourceMonitoringNotificationChannelRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

url, err := replaceVars(d, config, "https://monitoring.googleapis.com/v3/{{name}}")
if err != nil {
return err
}

res, err := sendRequest(config, "GET", url, nil)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("MonitoringNotificationChannel %q", d.Id()))
}

if err := d.Set("labels", flattenMonitoringNotificationChannelLabels(res["labels"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("name", flattenMonitoringNotificationChannelName(res["name"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("verification_status", flattenMonitoringNotificationChannelVerificationStatus(res["verificationStatus"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("type", flattenMonitoringNotificationChannelType(res["type"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("user_labels", flattenMonitoringNotificationChannelUserLabels(res["userLabels"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("description", flattenMonitoringNotificationChannelDescription(res["description"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("display_name", flattenMonitoringNotificationChannelDisplayName(res["displayName"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
if err := d.Set("enabled", flattenMonitoringNotificationChannelEnabled(res["enabled"])); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}
project, err := getProject(d, config)
if err != nil {
return err
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading NotificationChannel: %s", err)
}

return nil
}

func resourceMonitoringNotificationChannelUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})
labelsProp, err := expandMonitoringNotificationChannelLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
typeProp, err := expandMonitoringNotificationChannelType(d.Get("type"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("type"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, typeProp)) {
obj["type"] = typeProp
}
userLabelsProp, err := expandMonitoringNotificationChannelUserLabels(d.Get("user_labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("user_labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, userLabelsProp)) {
obj["userLabels"] = userLabelsProp
}
descriptionProp, err := expandMonitoringNotificationChannelDescription(d.Get("description"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
displayNameProp, err := expandMonitoringNotificationChannelDisplayName(d.Get("display_name"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) {
obj["displayName"] = displayNameProp
}
enabledProp, err := expandMonitoringNotificationChannelEnabled(d.Get("enabled"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) {
obj["enabled"] = enabledProp
}

lockName, err := replaceVars(d, config, "stackdriver/notifications/{{project}}")
if err != nil {
return err
}
mutexKV.Lock(lockName)
defer mutexKV.Unlock(lockName)

url, err := replaceVars(d, config, "https://monitoring.googleapis.com/v3/{{name}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Updating NotificationChannel %q: %#v", d.Id(), obj)
_, err = sendRequest(config, "PATCH", url, obj)

if err != nil {
return fmt.Errorf("Error updating NotificationChannel %q: %s", d.Id(), err)
}

return resourceMonitoringNotificationChannelRead(d, meta)
}

func resourceMonitoringNotificationChannelDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

lockName, err := replaceVars(d, config, "stackdriver/notifications/{{project}}")
if err != nil {
return err
}
mutexKV.Lock(lockName)
defer mutexKV.Unlock(lockName)

url, err := replaceVars(d, config, "https://monitoring.googleapis.com/v3/{{name}}")
if err != nil {
return err
}

var obj map[string]interface{}
log.Printf("[DEBUG] Deleting NotificationChannel %q", d.Id())
res, err := sendRequest(config, "DELETE", url, obj)
if err != nil {
return handleNotFoundError(err, d, "NotificationChannel")
}

log.Printf("[DEBUG] Finished deleting NotificationChannel %q: %#v", d.Id(), res)
return nil
}

func resourceMonitoringNotificationChannelImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {

config := meta.(*Config)

// current import_formats can't import id's with forward slashes in them.
parseImportId([]string{"(?P<name>.+)"}, d, config)

return []*schema.ResourceData{d}, nil
}

func flattenMonitoringNotificationChannelLabels(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelName(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelVerificationStatus(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelType(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelUserLabels(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelDescription(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelDisplayName(v interface{}) interface{} {
return v
}

func flattenMonitoringNotificationChannelEnabled(v interface{}) interface{} {
return v
}

func expandMonitoringNotificationChannelLabels(v interface{}, d *schema.ResourceData, config *Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
}
m := make(map[string]string)
for k, val := range v.(map[string]interface{}) {
m[k] = val.(string)
}
return m, nil
}

func expandMonitoringNotificationChannelType(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandMonitoringNotificationChannelUserLabels(v interface{}, d *schema.ResourceData, config *Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
}
m := make(map[string]string)
for k, val := range v.(map[string]interface{}) {
m[k] = val.(string)
}
return m, nil
}

func expandMonitoringNotificationChannelDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandMonitoringNotificationChannelDisplayName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandMonitoringNotificationChannelEnabled(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
79 changes: 79 additions & 0 deletions google/resource_monitoring_notification_channel_generated_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccMonitoringNotificationChannel_notificationChannelBasicExample(t *testing.T) {
t.Parallel()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckMonitoringNotificationChannelDestroy,
Steps: []resource.TestStep{
{
Config: testAccMonitoringNotificationChannel_notificationChannelBasicExample(acctest.RandString(10)),
},
{
ResourceName: "google_monitoring_notification_channel.basic",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccMonitoringNotificationChannel_notificationChannelBasicExample(val string) string {
return fmt.Sprintf(`
resource "google_monitoring_notification_channel" "basic" {
display_name = "Test Notification Channel-%s"
type = "email"
labels = {
email_address = "fake_email@blahblah.com"
}
}
`, val,
)
}

func testAccCheckMonitoringNotificationChannelDestroy(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_monitoring_notification_channel" {
continue
}

config := testAccProvider.Meta().(*Config)

url, err := replaceVarsForTest(rs, "https://monitoring.googleapis.com/v3/{{name}}")
if err != nil {
return err
}

_, err = sendRequest(config, "GET", url, nil)
if err == nil {
return fmt.Errorf("MonitoringNotificationChannel still exists at %s", url)
}
}

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

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
)

func TestAccMonitoringNotificationChannel_update(t *testing.T) {
t.Parallel()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckMonitoringNotificationChannelDestroy,
Steps: []resource.TestStep{
{
Config: testAccMonitoringNotificationChannel_update("email", `email_address = "fake_email@blahblah.com"`),
},
{
ResourceName: "google_monitoring_notification_channel.update",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccMonitoringNotificationChannel_update("sms", `number = "+15555379009"`),
},
{
ResourceName: "google_monitoring_notification_channel.update",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccMonitoringNotificationChannel_update(channel, labels string) string {
return fmt.Sprintf(`
resource "google_monitoring_notification_channel" "update" {
display_name = "IntTest Notification Channel"
type = "%s"
labels = {
%s
}
}
`, channel, labels,
)
}
112 changes: 112 additions & 0 deletions website/docs/r/monitoring_notification_channel.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in
# .github/CONTRIBUTING.md.
#
# ----------------------------------------------------------------------------
layout: "google"
page_title: "Google: google_monitoring_notification_channel"
sidebar_current: "docs-google-monitoring-notification-channel"
description: |-
A NotificationChannel is a medium through which an alert is delivered
when a policy violation is detected.
---

# google\_monitoring\_notification\_channel

A NotificationChannel is a medium through which an alert is delivered
when a policy violation is detected. Examples of channels include email, SMS,
and third-party messaging applications. Fields containing sensitive information
like authentication tokens or contact info are only partially populated on retrieval.


To get more information about NotificationChannel, see:

* [API documentation](https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.notificationChannels)
* How-to Guides
* [Official Documentation](https://cloud.google.com/monitoring/api/v3/)

<div class = "oics-button" style="float: right; margin: 0 0 -15px">
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=notification_channel_basic&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
</a>
</div>
## Example Usage - Notification Channel Basic


```hcl
resource "google_monitoring_notification_channel" "basic" {
display_name = "Test Notification Channel"
type = "email"
labels = {
email_address = "fake_email@blahblah.com"
}
}
```

## Argument Reference

The following arguments are supported:


* `type` -
(Required)
The type of the notification channel. This field matches the value of the NotificationChannelDescriptor.type field. See https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.notificationChannelDescriptors/list to get the list of valid values such as "email", "slack", etc...

* `display_name` -
(Required)
An optional human-readable name for this notification channel. It is recommended that you specify a non-empty and unique name in order to make it easier to identify the channels in your project, though this is not enforced. The display name is limited to 512 Unicode characters.


- - -


* `labels` -
(Optional)
Configuration fields that define the channel and its behavior. The permissible and required labels are specified in the NotificationChannelDescriptor.labels of the NotificationChannelDescriptor corresponding to the type field.

* `user_labels` -
(Optional)
User-supplied key/value data that does not need to conform to the corresponding NotificationChannelDescriptor's schema, unlike the labels field. This field is intended to be used for organizing and identifying the NotificationChannel objects.The field can contain up to 64 entries. Each key and value is limited to 63 Unicode characters or 128 bytes, whichever is smaller. Labels and values can contain only lowercase letters, numerals, underscores, and dashes. Keys must begin with a letter.

* `description` -
(Optional)
An optional human-readable description of this notification channel. This description may provide additional details, beyond the display name, for the channel. This may not exceeed 1024 Unicode characters.

* `enabled` -
(Optional)
Whether notifications are forwarded to the described channel. This makes it possible to disable delivery of notifications to a particular channel without removing the channel from all alerting policies that reference the channel. This is a more convenient approach when the change is temporary and you want to receive notifications from the same set of alerting policies on the channel at some point in the future.
* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.


## Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:


* `name` -
The full REST resource name for this channel. The syntax is:
projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]
The [CHANNEL_ID] is automatically assigned by the server on creation.

* `verification_status` -
Indicates whether this channel has been verified or not. On a ListNotificationChannels or GetNotificationChannel operation, this field is expected to be populated.If the value is UNVERIFIED, then it indicates that the channel is non-functioning (it both requires verification and lacks verification); otherwise, it is assumed that the channel works.If the channel is neither VERIFIED nor UNVERIFIED, it implies that the channel is of a type that does not require verification or that this specific channel has been exempted from verification because it was created prior to verification being required for channels of this type.This field cannot be modified using a standard UpdateNotificationChannel operation. To change the value of this field, you must call VerifyNotificationChannel.



## Import

NotificationChannel can be imported using any of these accepted formats:

```
$ terraform import google_monitoring_notification_channel.default {{name}}
```

0 comments on commit a10491a

Please sign in to comment.