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

Create SCC Mute config resource #13818

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
3 changes: 3 additions & 0 deletions .changelog/7332.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
google_scc_mute_config
```
5 changes: 3 additions & 2 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -991,9 +991,9 @@ func Provider() *schema.Provider {
return provider
}

// Generated resources: 265
// Generated resources: 266
// Generated IAM resources: 168
// Total generated resources: 433
// Total generated resources: 434
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -1374,6 +1374,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_secret_manager_secret_iam_member": ResourceIamMember(SecretManagerSecretIamSchema, SecretManagerSecretIamUpdaterProducer, SecretManagerSecretIdParseFunc),
"google_secret_manager_secret_iam_policy": ResourceIamPolicy(SecretManagerSecretIamSchema, SecretManagerSecretIamUpdaterProducer, SecretManagerSecretIdParseFunc),
"google_secret_manager_secret_version": ResourceSecretManagerSecretVersion(),
"google_scc_mute_config": ResourceSecurityCenterMuteConfig(),
"google_scc_notification_config": ResourceSecurityCenterNotificationConfig(),
"google_scc_source": ResourceSecurityCenterSource(),
"google_scc_source_iam_binding": ResourceIamBinding(SecurityCenterSourceIamSchema, SecurityCenterSourceIamUpdaterProducer, SecurityCenterSourceIdParseFunc),
Expand Down
366 changes: 366 additions & 0 deletions google/resource_scc_mute_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,366 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** Type: MMv1 ***
//
// ----------------------------------------------------------------------------
//
// 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"
"regexp"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func ResourceSecurityCenterMuteConfig() *schema.Resource {
return &schema.Resource{
Create: resourceSecurityCenterMuteConfigCreate,
Read: resourceSecurityCenterMuteConfigRead,
Update: resourceSecurityCenterMuteConfigUpdate,
Delete: resourceSecurityCenterMuteConfigDelete,

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

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(20 * time.Minute),
Update: schema.DefaultTimeout(20 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},

Schema: map[string]*schema.Schema{
"filter": {
Type: schema.TypeString,
Required: true,
Description: `An expression that defines the filter to apply across create/update
events of findings. While creating a filter string, be mindful of
the scope in which the mute configuration is being created. E.g.,
If a filter contains project = X but is created under the
project = Y scope, it might not match any findings.`,
},
"mute_config_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `Unique identifier provided by the client within the parent scope.`,
},
"parent": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `Resource name of the new mute configs's parent. Its format is
"organizations/[organization_id]", "folders/[folder_id]", or
"projects/[project_id]".`,
},
"description": {
Type: schema.TypeString,
Optional: true,
Description: `A description of the mute config.`,
},
"create_time": {
Type: schema.TypeString,
Computed: true,
Description: `The time at which the mute config was created. This field is set by
the server and will be ignored if provided on config creation.`,
},
"most_recent_editor": {
Type: schema.TypeString,
Computed: true,
Description: `Email address of the user who last edited the mute config. This
field is set by the server and will be ignored if provided on
config creation or update.`,
},
"name": {
Type: schema.TypeString,
Computed: true,
Description: `Name of the mute config. Its format is
organizations/{organization}/muteConfigs/{configId},
folders/{folder}/muteConfigs/{configId},
or projects/{project}/muteConfigs/{configId}`,
},
"update_time": {
Type: schema.TypeString,
Computed: true,
Description: `Output only. The most recent time at which the mute config was
updated. This field is set by the server and will be ignored if
provided on config creation or update.`,
},
},
UseJSONNumber: true,
}
}

func resourceSecurityCenterMuteConfigCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

obj := make(map[string]interface{})
descriptionProp, err := expandSecurityCenterMuteConfigDescription(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
}
filterProp, err := expandSecurityCenterMuteConfigFilter(d.Get("filter"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("filter"); !isEmptyValue(reflect.ValueOf(filterProp)) && (ok || !reflect.DeepEqual(v, filterProp)) {
obj["filter"] = filterProp
}

url, err := replaceVars(d, config, "{{SecurityCenterBasePath}}{{parent}}/muteConfigs?muteConfigId={{mute_config_id}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new MuteConfig: %#v", obj)
billingProject := ""

// err == nil indicates that the billing_project value was found
if bp, err := getBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating MuteConfig: %s", err)
}
if err := d.Set("name", flattenSecurityCenterMuteConfigName(res["name"], d, config)); err != nil {
return fmt.Errorf(`Error setting computed identity field "name": %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 MuteConfig %q: %#v", d.Id(), res)

return resourceSecurityCenterMuteConfigRead(d, meta)
}

func resourceSecurityCenterMuteConfigRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

url, err := replaceVars(d, config, "{{SecurityCenterBasePath}}{{name}}")
if err != nil {
return err
}

billingProject := ""

// err == nil indicates that the billing_project value was found
if bp, err := getBillingProject(d, config); err == nil {
billingProject = bp
}

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

if err := d.Set("name", flattenSecurityCenterMuteConfigName(res["name"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("description", flattenSecurityCenterMuteConfigDescription(res["description"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("filter", flattenSecurityCenterMuteConfigFilter(res["filter"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("create_time", flattenSecurityCenterMuteConfigCreateTime(res["createTime"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("update_time", flattenSecurityCenterMuteConfigUpdateTime(res["updateTime"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("most_recent_editor", flattenSecurityCenterMuteConfigMostRecentEditor(res["mostRecentEditor"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}

return nil
}

func resourceSecurityCenterMuteConfigUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

billingProject := ""

obj := make(map[string]interface{})
descriptionProp, err := expandSecurityCenterMuteConfigDescription(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
}
filterProp, err := expandSecurityCenterMuteConfigFilter(d.Get("filter"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("filter"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, filterProp)) {
obj["filter"] = filterProp
}

url, err := replaceVars(d, config, "{{SecurityCenterBasePath}}{{name}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Updating MuteConfig %q: %#v", d.Id(), obj)
updateMask := []string{}

if d.HasChange("description") {
updateMask = append(updateMask, "description")
}

if d.HasChange("filter") {
updateMask = append(updateMask, "filter")
}
// updateMask is a URL parameter but not present in the schema, so replaceVars
// won't set it
url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}

// err == nil indicates that the billing_project value was found
if bp, err := getBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := sendRequestWithTimeout(config, "PATCH", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutUpdate))

if err != nil {
return fmt.Errorf("Error updating MuteConfig %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished updating MuteConfig %q: %#v", d.Id(), res)
}

return resourceSecurityCenterMuteConfigRead(d, meta)
}

func resourceSecurityCenterMuteConfigDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

billingProject := ""

url, err := replaceVars(d, config, "{{SecurityCenterBasePath}}{{name}}")
if err != nil {
return err
}

var obj map[string]interface{}
log.Printf("[DEBUG] Deleting MuteConfig %q", d.Id())

// err == nil indicates that the billing_project value was found
if bp, err := getBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete))
if err != nil {
return handleNotFoundError(err, d, "MuteConfig")
}

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

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

if err := parseImportId([]string{"(?P<name>.+)"}, d, config); err != nil {
return nil, err
}

// current import_formats can't import fields with forward slashes in their value
name := d.Get("name").(string)

matched, err := regexp.MatchString("(organizations|folders|projects)/.+/muteConfigs/.+", name)
if err != nil {
return nil, fmt.Errorf("error validating import name: %s", err)
}

if !matched {
return nil, fmt.Errorf("error validating import name: %s does not fit naming for muteConfigs. Expected %s",
name, "organizations/{organization}/muteConfigs/{configId}, folders/{folder}/muteConfigs/{configId} or projects/{project}/muteConfigs/{configId}")
}

if err := d.Set("name", name); err != nil {
return nil, fmt.Errorf("Error setting name: %s", err)
}

// mute_config_id and parent are not returned by the API and therefore need to be set manually
stringParts := strings.Split(d.Get("name").(string), "/")
if err := d.Set("mute_config_id", stringParts[3]); err != nil {
return nil, fmt.Errorf("Error setting mute_config_id: %s", err)
}

if err := d.Set("parent", fmt.Sprintf("%s/%s", stringParts[0], stringParts[1])); err != nil {
return nil, fmt.Errorf("Error setting mute_config_id: %s", err)
}

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

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

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

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

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

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

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

func expandSecurityCenterMuteConfigDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandSecurityCenterMuteConfigFilter(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
Loading