Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add log_level, plural event_notification_configs to IoT registry #2206

Merged
merged 7 commits into from
Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/terraform
2 changes: 1 addition & 1 deletion build/terraform-beta
2 changes: 1 addition & 1 deletion build/terraform-mapper
138 changes: 126 additions & 12 deletions third_party/terraform/resources/resource_cloudiot_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package google

import (
"fmt"
"github.com/hashicorp/terraform/helper/validation"
"regexp"
"strings"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"google.golang.org/api/cloudiot/v1"
)

Expand Down Expand Up @@ -34,7 +34,7 @@ func resourceCloudIoTRegistry() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateCloudIoTID,
ValidateFunc: validateCloudIotID,
},
"project": {
Type: schema.TypeString,
Expand All @@ -48,9 +48,19 @@ func resourceCloudIoTRegistry() *schema.Resource {
Computed: true,
ForceNew: true,
},
"log_level": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: emptyOrDefaultStringSuppress(""),
ValidateFunc: validation.StringInSlice(
[]string{"", "NONE", "ERROR", "INFO", "DEBUG"}, false),
},
"event_notification_config": {
Type: schema.TypeMap,
Optional: true,
Type: schema.TypeMap,
Optional: true,
Computed: true,
Deprecated: "eventNotificationConfig has been deprecated in favor of eventNotificationConfigs (plural). Please switch to using the plural field.",
ConflictsWith: []string{"event_notification_configs"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"pubsub_topic_name": {
Expand All @@ -61,6 +71,27 @@ func resourceCloudIoTRegistry() *schema.Resource {
},
},
},
"event_notification_configs": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 10,
ConflictsWith: []string{"event_notification_config"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"pubsub_topic_name": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"subfolder_matches": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateCloudIotRegistrySubfolderMatch,
},
},
},
},
"state_notification_config": {
Type: schema.TypeMap,
Optional: true,
Expand Down Expand Up @@ -135,6 +166,17 @@ func resourceCloudIoTRegistry() *schema.Resource {
}
}

func buildEventNotificationConfigs(v []interface{}) []*cloudiot.EventNotificationConfig {
cfgList := make([]*cloudiot.EventNotificationConfig, 0, len(v))
for _, cfgRaw := range v {
if cfgRaw == nil {
continue
}
cfgList = append(cfgList, buildEventNotificationConfig(cfgRaw.(map[string]interface{})))
}
return cfgList
}

func buildEventNotificationConfig(config map[string]interface{}) *cloudiot.EventNotificationConfig {
if v, ok := config["pubsub_topic_name"]; ok {
return &cloudiot.EventNotificationConfig{
Expand Down Expand Up @@ -192,10 +234,13 @@ func expandCredentials(credentials []interface{}) []*cloudiot.RegistryCredential

func createDeviceRegistry(d *schema.ResourceData) *cloudiot.DeviceRegistry {
deviceRegistry := &cloudiot.DeviceRegistry{}
if v, ok := d.GetOk("event_notification_config"); ok {
deviceRegistry.EventNotificationConfigs = make([]*cloudiot.EventNotificationConfig, 1, 1)
deviceRegistry.EventNotificationConfigs[0] = buildEventNotificationConfig(v.(map[string]interface{}))
if v, ok := d.GetOk("event_notification_configs"); ok {
deviceRegistry.EventNotificationConfigs = buildEventNotificationConfigs(v.([]interface{}))
} else if v, ok := d.GetOk("event_notification_config"); ok {
deviceRegistry.EventNotificationConfigs = []*cloudiot.EventNotificationConfig{
buildEventNotificationConfig(v.(map[string]interface{}))}
}

if v, ok := d.GetOk("state_notification_config"); ok {
deviceRegistry.StateNotificationConfig = buildStateNotificationConfig(v.(map[string]interface{}))
}
Expand All @@ -208,6 +253,11 @@ func createDeviceRegistry(d *schema.ResourceData) *cloudiot.DeviceRegistry {
if v, ok := d.GetOk("credentials"); ok {
deviceRegistry.Credentials = expandCredentials(v.([]interface{}))
}
if v, ok := d.GetOk("log_level"); ok {
deviceRegistry.LogLevel = v.(string)
}
deviceRegistry.ForceSendFields = append(deviceRegistry.ForceSendFields, "logLevel")

return deviceRegistry
}

Expand Down Expand Up @@ -251,14 +301,23 @@ func resourceCloudIoTRegistryUpdate(d *schema.ResourceData, meta interface{}) er

d.Partial(true)

if d.HasChange("event_notification_configs") {
hasChanged = true
updateMask = append(updateMask, "event_notification_configs")
if v, ok := d.GetOk("event_notification_configs"); ok {
deviceRegistry.EventNotificationConfigs = buildEventNotificationConfigs(v.([]interface{}))
}
}

if d.HasChange("event_notification_config") {
hasChanged = true
updateMask = append(updateMask, "event_notification_configs")
if v, ok := d.GetOk("event_notification_config"); ok {
deviceRegistry.EventNotificationConfigs = make([]*cloudiot.EventNotificationConfig, 1, 1)
deviceRegistry.EventNotificationConfigs[0] = buildEventNotificationConfig(v.(map[string]interface{}))
deviceRegistry.EventNotificationConfigs = []*cloudiot.EventNotificationConfig{
buildEventNotificationConfig(v.(map[string]interface{}))}
}
}

if d.HasChange("state_notification_config") {
hasChanged = true
updateMask = append(updateMask, "state_notification_config.pubsub_topic_name")
Expand Down Expand Up @@ -287,6 +346,14 @@ func resourceCloudIoTRegistryUpdate(d *schema.ResourceData, meta interface{}) er
deviceRegistry.Credentials = expandCredentials(v.([]interface{}))
}
}
if d.HasChange("log_level") {
hasChanged = true
updateMask = append(updateMask, "log_level")
if v, ok := d.GetOk("log_level"); ok {
deviceRegistry.LogLevel = v.(string)
deviceRegistry.ForceSendFields = append(deviceRegistry.ForceSendFields, "logLevel")
}
}
if hasChanged {
_, err := config.clientCloudIoT.Projects.Locations.Registries.Patch(d.Id(),
deviceRegistry).UpdateMask(strings.Join(updateMask, ",")).Do()
Expand All @@ -297,26 +364,49 @@ func resourceCloudIoTRegistryUpdate(d *schema.ResourceData, meta interface{}) er
d.SetPartial(updateMaskItem)
}
}

d.Partial(false)
return resourceCloudIoTRegistryRead(d, meta)
}

func flattenCloudIotRegistryEventNotificationConfigs(cfgs []*cloudiot.EventNotificationConfig, d *schema.ResourceData) []interface{} {
ls := make([]interface{}, 0, len(cfgs))
for _, cfg := range cfgs {
if cfg == nil {
continue
}
ls = append(ls, map[string]interface{}{
"subfolder_matches": cfg.SubfolderMatches,
"pubsub_topic_name": cfg.PubsubTopicName,
})
}
return ls
}

func resourceCloudIoTRegistryRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
name := d.Id()
res, err := config.clientCloudIoT.Projects.Locations.Registries.Get(name).Do()
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("Registry %q", name))
}

d.Set("name", res.Id)

if len(res.EventNotificationConfigs) > 0 {
eventConfig := map[string]string{"pubsub_topic_name": res.EventNotificationConfigs[0].PubsubTopicName}
d.Set("event_notification_config", eventConfig)
cfgs := flattenCloudIotRegistryEventNotificationConfigs(res.EventNotificationConfigs, d)
if err := d.Set("event_notification_configs", cfgs); err != nil {
return fmt.Errorf("Error reading Registry: %s", err)
}
if err := d.Set("event_notification_config", map[string]string{
"pubsub_topic_name": res.EventNotificationConfigs[0].PubsubTopicName,
}); err != nil {
return fmt.Errorf("Error reading Registry: %s", err)
}
} else {
d.Set("event_notification_configs", nil)
d.Set("event_notification_config", nil)
}

pubsubTopicName := res.StateNotificationConfig.PubsubTopicName
if pubsubTopicName != "" {
d.Set("state_notification_config",
Expand All @@ -337,6 +427,8 @@ func resourceCloudIoTRegistryRead(d *schema.ResourceData, meta interface{}) erro
credentials[i]["public_key_certificate"] = pubcert
}
d.Set("credentials", credentials)
d.Set("log_level", res.LogLevel)

return nil
}

Expand Down Expand Up @@ -369,3 +461,25 @@ func resourceCloudIoTRegistryStateImporter(d *schema.ResourceData, meta interfac
d.SetId(id)
return []*schema.ResourceData{d}, nil
}

func validateCloudIotID(v interface{}, k string) (warnings []string, errors []error) {
value := v.(string)
if strings.HasPrefix(value, "goog") {
errors = append(errors, fmt.Errorf(
"%q (%q) can not start with \"goog\"", k, value))
}
if !regexp.MustCompile(CloudIoTIdRegex).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q (%q) doesn't match regexp %q", k, value, CloudIoTIdRegex))
}
return
}

func validateCloudIotRegistrySubfolderMatch(v interface{}, k string) (warnings []string, errors []error) {
value := v.(string)
if strings.HasPrefix(value, "/") {
errors = append(errors, fmt.Errorf(
"%q (%q) can not start with '/'", k, value))
}
return
}
Loading