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

Update resource SCC Mute Config with expiry time field #9273

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/12979.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
securitycenter: added `type`, `expiry_time` field to `google_scc_mute_config` resource
```
71 changes: 71 additions & 0 deletions google-beta/services/securitycenter/resource_scc_mute_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/verify"
)

func ResourceSecurityCenterMuteConfig() *schema.Resource {
Expand Down Expand Up @@ -78,6 +79,22 @@ project = Y scope, it might not match any findings.`,
Optional: true,
Description: `A description of the mute config.`,
},
"expiry_time": {
Type: schema.TypeString,
Optional: true,
Description: `Optional. The expiry of the mute config. Only applicable for dynamic configs.
If the expiry is set, when the config expires, it is removed from all findings.

A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to
nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`,
},
"type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"MUTE_CONFIG_TYPE_UNSPECIFIED", "STATIC", "DYNAMIC", ""}),
Description: `The type of the mute config, which determines what type of mute state the config affects. Default value: "DYNAMIC" Possible values: ["MUTE_CONFIG_TYPE_UNSPECIFIED", "STATIC", "DYNAMIC"]`,
Default: "DYNAMIC",
},
"create_time": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -131,6 +148,18 @@ func resourceSecurityCenterMuteConfigCreate(d *schema.ResourceData, meta interfa
} else if v, ok := d.GetOkExists("filter"); !tpgresource.IsEmptyValue(reflect.ValueOf(filterProp)) && (ok || !reflect.DeepEqual(v, filterProp)) {
obj["filter"] = filterProp
}
typeProp, err := expandSecurityCenterMuteConfigType(d.Get("type"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("type"); !tpgresource.IsEmptyValue(reflect.ValueOf(typeProp)) && (ok || !reflect.DeepEqual(v, typeProp)) {
obj["type"] = typeProp
}
expiryTimeProp, err := expandSecurityCenterMuteConfigExpiryTime(d.Get("expiry_time"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("expiry_time"); !tpgresource.IsEmptyValue(reflect.ValueOf(expiryTimeProp)) && (ok || !reflect.DeepEqual(v, expiryTimeProp)) {
obj["expiryTime"] = expiryTimeProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{SecurityCenterBasePath}}{{parent}}/muteConfigs?muteConfigId={{mute_config_id}}")
if err != nil {
Expand Down Expand Up @@ -225,6 +254,12 @@ func resourceSecurityCenterMuteConfigRead(d *schema.ResourceData, meta interface
if err := d.Set("most_recent_editor", flattenSecurityCenterMuteConfigMostRecentEditor(res["mostRecentEditor"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("type", flattenSecurityCenterMuteConfigType(res["type"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}
if err := d.Set("expiry_time", flattenSecurityCenterMuteConfigExpiryTime(res["expiryTime"], d, config)); err != nil {
return fmt.Errorf("Error reading MuteConfig: %s", err)
}

return nil
}
Expand All @@ -251,6 +286,18 @@ func resourceSecurityCenterMuteConfigUpdate(d *schema.ResourceData, meta interfa
} else if v, ok := d.GetOkExists("filter"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, filterProp)) {
obj["filter"] = filterProp
}
typeProp, err := expandSecurityCenterMuteConfigType(d.Get("type"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("type"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, typeProp)) {
obj["type"] = typeProp
}
expiryTimeProp, err := expandSecurityCenterMuteConfigExpiryTime(d.Get("expiry_time"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("expiry_time"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, expiryTimeProp)) {
obj["expiryTime"] = expiryTimeProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{SecurityCenterBasePath}}{{name}}")
if err != nil {
Expand All @@ -268,6 +315,14 @@ func resourceSecurityCenterMuteConfigUpdate(d *schema.ResourceData, meta interfa
if d.HasChange("filter") {
updateMask = append(updateMask, "filter")
}

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

if d.HasChange("expiry_time") {
updateMask = append(updateMask, "expiryTime")
}
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
Expand Down Expand Up @@ -407,10 +462,26 @@ func flattenSecurityCenterMuteConfigMostRecentEditor(v interface{}, d *schema.Re
return v
}

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

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

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

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

func expandSecurityCenterMuteConfigType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandSecurityCenterMuteConfigExpiryTime(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ api_resource_type_kind: 'MuteConfig'
fields:
- field: 'create_time'
- field: 'description'
- field: 'expiry_time'
- field: 'filter'
- field: 'most_recent_editor'
- field: 'mute_config_id'
provider_only: true
- field: 'name'
- field: 'parent'
provider_only: true
- field: 'type'
- field: 'update_time'
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ resource "google_scc_mute_config" "default" {
parent = "organizations/%{org_id}"
filter = "category: \"OS_VULNERABILITY\""
description = "My Mute Config"
type = "DYNAMIC"
expiry_time = "2215-02-03T15:01:23Z"
}
`, context)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package securitycenter_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
)

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

context := map[string]interface{}{
"org_id": envvar.GetTestOrgFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"random": {},
"time": {},
},
Steps: []resource.TestStep{
{
Config: testAccSecurityCenterMuteConfig_basic(context),
},
{
ResourceName: "google_scc_mute_config.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"mute_config_id",
},
},
{
Config: testAccSecurityCenterMuteConfig_update(context),
},
{
ResourceName: "google_scc_mute_config.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"mute_config_id",
},
},
},
})
}

func testAccSecurityCenterMuteConfig_basic(context map[string]interface{}) string {
return acctest.Nprintf(`

resource "google_scc_mute_config" "default" {
mute_config_id = "tf-test-mute-config-%{random_suffix}"
parent = "organizations/%{org_id}"
filter = "category: \"OS_VULNERABILITY\""
description = "A Test Mute Config"
type = "DYNAMIC"
expiry_time = "2215-02-03T15:01:23Z"
}
`, context)
}

func testAccSecurityCenterMuteConfig_update(context map[string]interface{}) string {
return acctest.Nprintf(`

resource "google_scc_mute_config" "default" {
mute_config_id = "tf-test-mute-config-%{random_suffix}"
parent = "organizations/%{org_id}"
filter = "category: \"OS_VULNERABILITY\""
description = "An Updated Test Mute Config"
type = "DYNAMIC"
expiry_time = "2215-02-03T15:01:23Z"
}
`, context)
}
15 changes: 15 additions & 0 deletions website/docs/r/scc_mute_config.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ resource "google_scc_mute_config" "default" {
parent = "organizations/123456789"
filter = "category: \"OS_VULNERABILITY\""
description = "My Mute Config"
type = "DYNAMIC"
expiry_time = "2215-02-03T15:01:23Z"
}
```

Expand Down Expand Up @@ -75,6 +77,19 @@ The following arguments are supported:
(Optional)
A description of the mute config.

* `type` -
(Optional)
The type of the mute config, which determines what type of mute state the config affects.
Default value is `DYNAMIC`.
Possible values are: `MUTE_CONFIG_TYPE_UNSPECIFIED`, `STATIC`, `DYNAMIC`.

* `expiry_time` -
(Optional)
Optional. The expiry of the mute config. Only applicable for dynamic configs.
If the expiry is set, when the config expires, it is removed from all findings.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to
nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".


## Attributes Reference

Expand Down