diff --git a/google-beta/fwtransport/framework_config_test.go b/google-beta/fwtransport/framework_config_test.go index 3216b51a7f..7d4816be26 100644 --- a/google-beta/fwtransport/framework_config_test.go +++ b/google-beta/fwtransport/framework_config_test.go @@ -336,63 +336,61 @@ func TestFrameworkProvider_LoadAndValidateFramework_credentials(t *testing.T) { } } -// NOTE: these tests can't run in Cloud Build due to ADC locating credentials despite `GOOGLE_APPLICATION_CREDENTIALS` being unset -// See https://cloud.google.com/docs/authentication/application-default-credentials#search_order -// Also, when running these tests locally you need to run `gcloud auth application-default revoke` to ensure your machine isn't supplying ADCs -// func TestFrameworkProvider_LoadAndValidateFramework_credentials_unknown(t *testing.T) { -// // This test case is kept separate from other credentials tests, as it requires comparing -// // error messages returned by two different error states: -// // - When credentials = Null -// // - When credentials = Unknown - -// t.Run("the same error is returned whether credentials is set as a null or unknown value (and access_token isn't set)", func(t *testing.T) { -// // Arrange -// acctest.UnsetTestProviderConfigEnvs(t) - -// ctx := context.Background() -// tfVersion := "foobar" -// providerversion := "999" - -// impersonateServiceAccountDelegates, _ := types.ListValue(types.StringType, []attr.Value{}) // empty list - -// // Null data and error collection -// diagsNull := diag.Diagnostics{} -// dataNull := fwmodels.ProviderModel{ -// Credentials: types.StringNull(), -// } -// dataNull.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates - -// // Unknown data and error collection -// diagsUnknown := diag.Diagnostics{} -// dataUnknown := fwmodels.ProviderModel{ -// Credentials: types.StringUnknown(), -// } -// dataUnknown.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates - -// pNull := fwtransport.FrameworkProviderConfig{} -// pUnknown := fwtransport.FrameworkProviderConfig{} - -// // Act -// pNull.LoadAndValidateFramework(ctx, &dataNull, tfVersion, &diagsNull, providerversion) -// pUnknown.LoadAndValidateFramework(ctx, &dataUnknown, tfVersion, &diagsUnknown, providerversion) - -// // Assert -// if !diagsNull.HasError() { -// t.Fatalf("expect errors when credentials is null, but [%d] errors occurred", diagsNull.ErrorsCount()) -// } -// if !diagsUnknown.HasError() { -// t.Fatalf("expect errors when credentials is unknown, but [%d] errors occurred", diagsUnknown.ErrorsCount()) -// } - -// errNull := diagsNull.Errors() -// errUnknown := diagsUnknown.Errors() -// for i := 0; i < len(errNull); i++ { -// if errNull[i] != errUnknown[i] { -// t.Fatalf("expect errors to be the same for null and unknown credentials values, instead got \nnull=`%s` \nunknown=%s", errNull[i], errUnknown[i]) -// } -// } -// }) -// } +func TestFrameworkProvider_LoadAndValidateFramework_credentials_unknown(t *testing.T) { + // This test case is kept separate from other credentials tests, as it requires comparing + // error messages returned by two different error states: + // - When credentials = Null + // - When credentials = Unknown + + t.Run("the same error is returned whether credentials is set as a null or unknown value (and access_token isn't set)", func(t *testing.T) { + + // Arrange + acctest.UnsetTestProviderConfigEnvs(t) + + ctx := context.Background() + tfVersion := "foobar" + providerversion := "999" + + impersonateServiceAccountDelegates, _ := types.ListValue(types.StringType, []attr.Value{}) // empty list + + // Null data and error collection + diagsNull := diag.Diagnostics{} + dataNull := fwmodels.ProviderModel{ + Credentials: types.StringNull(), + } + dataNull.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates + + // Unknown data and error collection + diagsUnknown := diag.Diagnostics{} + dataUnknown := fwmodels.ProviderModel{ + Credentials: types.StringUnknown(), + } + dataUnknown.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates + + pNull := fwtransport.FrameworkProviderConfig{} + pUnknown := fwtransport.FrameworkProviderConfig{} + + // Act + pNull.LoadAndValidateFramework(ctx, &dataNull, tfVersion, &diagsNull, providerversion) + pUnknown.LoadAndValidateFramework(ctx, &dataUnknown, tfVersion, &diagsUnknown, providerversion) + + // Assert + if !diagsNull.HasError() { + t.Fatalf("expect errors when credentials is null, but [%d] errors occurred", diagsNull.ErrorsCount()) + } + if !diagsUnknown.HasError() { + t.Fatalf("expect errors when credentials is unknown, but [%d] errors occurred", diagsUnknown.ErrorsCount()) + } + + errNull := diagsNull.Errors() + errUnknown := diagsUnknown.Errors() + for i := 0; i < len(errNull); i++ { + if errNull[i] != errUnknown[i] { + t.Fatalf("expect errors to be the same for null and unknown credentials values, instead got \nnull=`%s` \nunknown=%s", errNull[i], errUnknown[i]) + } + } + }) +} func TestFrameworkProvider_LoadAndValidateFramework_billingProject(t *testing.T) { diff --git a/google-beta/provider/provider.go b/google-beta/provider/provider.go index 2e8b827fa4..f7e3a237e4 100644 --- a/google-beta/provider/provider.go +++ b/google-beta/provider/provider.go @@ -871,7 +871,6 @@ func DatasourceMapWithErrors() (map[string]*schema.Resource, error) { "google_beyondcorp_app_gateway": beyondcorp.DataSourceGoogleBeyondcorpAppGateway(), "google_billing_account": billing.DataSourceGoogleBillingAccount(), "google_bigquery_default_service_account": bigquery.DataSourceGoogleBigqueryDefaultServiceAccount(), - "google_certificate_manager_certificate_map": certificatemanager.DataSourceGoogleCertificateManagerCertificateMap(), "google_cloudbuild_trigger": cloudbuild.DataSourceGoogleCloudBuildTrigger(), "google_cloudfunctions_function": cloudfunctions.DataSourceGoogleCloudFunctionsFunction(), "google_cloudfunctions2_function": cloudfunctions2.DataSourceGoogleCloudFunctions2Function(), @@ -1114,9 +1113,9 @@ func DatasourceMapWithErrors() (map[string]*schema.Resource, error) { }) } -// Generated resources: 381 +// Generated resources: 380 // Generated IAM resources: 237 -// Total generated resources: 618 +// Total generated resources: 617 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -1664,7 +1663,6 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_secret_manager_secret_version": secretmanager.ResourceSecretManagerSecretVersion(), "google_scc_mute_config": securitycenter.ResourceSecurityCenterMuteConfig(), "google_scc_notification_config": securitycenter.ResourceSecurityCenterNotificationConfig(), - "google_scc_project_custom_module": securitycenter.ResourceSecurityCenterProjectCustomModule(), "google_scc_source": securitycenter.ResourceSecurityCenterSource(), "google_scc_source_iam_binding": tpgiamresource.ResourceIamBinding(securitycenter.SecurityCenterSourceIamSchema, securitycenter.SecurityCenterSourceIamUpdaterProducer, securitycenter.SecurityCenterSourceIdParseFunc), "google_scc_source_iam_member": tpgiamresource.ResourceIamMember(securitycenter.SecurityCenterSourceIamSchema, securitycenter.SecurityCenterSourceIamUpdaterProducer, securitycenter.SecurityCenterSourceIdParseFunc), diff --git a/google-beta/services/certificatemanager/data_source_google_certificate_manager_certificate_map.go b/google-beta/services/certificatemanager/data_source_google_certificate_manager_certificate_map.go deleted file mode 100644 index 0481f3461b..0000000000 --- a/google-beta/services/certificatemanager/data_source_google_certificate_manager_certificate_map.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 -package certificatemanager - -import ( - "fmt" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" - transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" -) - -func DataSourceGoogleCertificateManagerCertificateMap() *schema.Resource { - - dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceCertificateManagerCertificateMap().Schema) - tpgresource.AddRequiredFieldsToSchema(dsSchema, "name") - tpgresource.AddOptionalFieldsToSchema(dsSchema, "project") - - return &schema.Resource{ - Read: dataSourceGoogleCertificateManagerCertificateMapRead, - Schema: dsSchema, - } -} - -func dataSourceGoogleCertificateManagerCertificateMapRead(d *schema.ResourceData, meta interface{}) error { - config := meta.(*transport_tpg.Config) - - name := d.Get("name").(string) - - project, err := tpgresource.GetProject(d, config) - if err != nil { - return err - } - - id := fmt.Sprintf("projects/%s/locations/global/certificateMaps/%s", project, name) - d.SetId(id) - err = resourceCertificateManagerCertificateMapRead(d, meta) - if err != nil { - return err - } - - if d.Id() == "" { - return fmt.Errorf("%s not found", id) - } - return nil -} diff --git a/google-beta/services/certificatemanager/data_source_google_certificate_manager_certificate_map_test.go b/google-beta/services/certificatemanager/data_source_google_certificate_manager_certificate_map_test.go deleted file mode 100644 index cf96373730..0000000000 --- a/google-beta/services/certificatemanager/data_source_google_certificate_manager_certificate_map_test.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 -package certificatemanager_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar" -) - -func TestAccDataSourceGoogleCertificateManagerCertificateMap_basic(t *testing.T) { - t.Parallel() - - project := envvar.GetTestProjectFromEnv() - - description := "My acceptance data source test certificate map" - name := fmt.Sprintf("tf-test-certificate-map-%d", acctest.RandInt(t)) - id := fmt.Sprintf("projects/%s/locations/global/certificateMaps/%s", project, name) - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - Steps: []resource.TestStep{ - { - Config: testAccDataSourceGoogleCertificateManagerCertificateMap_basic(name, description), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.google_certificate_manager_certificate_map.cert_map_data", "id", id), - resource.TestCheckResourceAttr("data.google_certificate_manager_certificate_map.cert_map_data", "description", description), - resource.TestCheckResourceAttr("data.google_certificate_manager_certificate_map.cert_map_data", "name", name), - ), - }, - }, - }) -} - -func testAccDataSourceGoogleCertificateManagerCertificateMap_basic(certificateMapName, certificateMapDescription string) string { - return fmt.Sprintf(` -resource "google_certificate_manager_certificate_map" "cert_map" { - name = "%s" - description = "%s" - labels = { - "terraform" : true, - "acc-test" : true, - } -} -data "google_certificate_manager_certificate_map" "cert_map_data" { - name = google_certificate_manager_certificate_map.cert_map.name -} -`, certificateMapName, certificateMapDescription) -} - -func TestAccDataSourceGoogleCertificateManagerCertificateMap_certificateMapEntryUsingMapDatasource(t *testing.T) { - t.Parallel() - - project := envvar.GetTestProjectFromEnv() - - certName := fmt.Sprintf("tf-test-certificate-%d", acctest.RandInt(t)) - mapEntryName := fmt.Sprintf("tf-test-certificate-map-entry-%d", acctest.RandInt(t)) - mapName := fmt.Sprintf("tf-test-certificate-map-%d", acctest.RandInt(t)) - id := fmt.Sprintf("projects/%s/locations/global/certificateMaps/%s", project, mapName) - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - Steps: []resource.TestStep{ - { - Config: testAccDataSourceGoogleCertificateManagerCertificateMap_certificateMapEntryUsingMapDatasource(mapName, mapEntryName, certName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.google_certificate_manager_certificate_map.cert_map_data", "id", id), - resource.TestCheckResourceAttr("data.google_certificate_manager_certificate_map.cert_map_data", "name", mapName), - resource.TestCheckResourceAttr("google_certificate_manager_certificate_map_entry.cert_map_entry", "map", mapName), // check that the certificate map entry is referencing the data source - - ), - }, - }, - }) -} - -func testAccDataSourceGoogleCertificateManagerCertificateMap_certificateMapEntryUsingMapDatasource(certificateMapName, certificateMapEntryName, certificateName string) string { - return fmt.Sprintf(` -resource "google_certificate_manager_certificate_map" "cert_map" { - name = "%s" - description = "certificate map example created for testing data sources in TF" - labels = { - "terraform" : true, - "acc-test" : true, - } -} -data "google_certificate_manager_certificate_map" "cert_map_data" { - name = google_certificate_manager_certificate_map.cert_map.name -} -resource "google_certificate_manager_certificate" "certificate" { - name = "%s" - description = "Global cert" - self_managed { - pem_certificate = file("test-fixtures/cert.pem") - pem_private_key = file("test-fixtures/private-key.pem") - } -} -resource "google_certificate_manager_certificate_map_entry" "cert_map_entry" { - name = "%s" - description = "certificate map entry that reference a data source of certificate map and a self managed certificate" - map = data.google_certificate_manager_certificate_map.cert_map_data.name - certificates = [google_certificate_manager_certificate.certificate.id] - matcher = "PRIMARY" -} -`, certificateMapName, certificateName, certificateMapEntryName) -} diff --git a/google-beta/services/identityplatform/resource_identity_platform_config.go b/google-beta/services/identityplatform/resource_identity_platform_config.go index adb560bf31..3dddf5d836 100644 --- a/google-beta/services/identityplatform/resource_identity_platform_config.go +++ b/google-beta/services/identityplatform/resource_identity_platform_config.go @@ -162,7 +162,6 @@ func ResourceIdentityPlatformConfig() *schema.Resource { }, "sign_in": { Type: schema.TypeList, - Computed: true, Optional: true, Description: `Configuration related to local sign in methods.`, MaxItems: 1, diff --git a/google-beta/services/identityplatform/resource_identity_platform_config_generated_test.go b/google-beta/services/identityplatform/resource_identity_platform_config_generated_test.go index b3929f7142..a618a98482 100644 --- a/google-beta/services/identityplatform/resource_identity_platform_config_generated_test.go +++ b/google-beta/services/identityplatform/resource_identity_platform_config_generated_test.go @@ -119,6 +119,7 @@ resource "google_identity_platform_config" "default" { } func TestAccIdentityPlatformConfig_identityPlatformConfigMinimalExample(t *testing.T) { + acctest.SkipIfVcr(t) t.Parallel() context := map[string]interface{}{ @@ -163,10 +164,6 @@ resource "google_project_service" "identitytoolkit" { resource "google_identity_platform_config" "default" { project = google_project.default.project_id - - depends_on = [ - google_project_service.identitytoolkit - ] } `, context) } diff --git a/google-beta/services/osconfig/resource_os_config_patch_deployment.go b/google-beta/services/osconfig/resource_os_config_patch_deployment.go index 7a200334e8..b7dd984023 100644 --- a/google-beta/services/osconfig/resource_os_config_patch_deployment.go +++ b/google-beta/services/osconfig/resource_os_config_patch_deployment.go @@ -552,8 +552,7 @@ be executed directly, which will likely only succeed for scripts with shebang li Type: schema.TypeString, ValidateFunc: verify.ValidateEnum([]string{"CRITICAL", "SECURITY", "DEFINITION", "DRIVER", "FEATURE_PACK", "SERVICE_PACK", "TOOL", "UPDATE_ROLLUP", "UPDATE"}), }, - ConflictsWith: []string{"patch_config.0.windows_update.0.exclusive_patches"}, - AtLeastOneOf: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes", "patch_config.0.windows_update.0.exclusive_patches"}, + ExactlyOneOf: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes", "patch_config.0.windows_update.0.exclusive_patches"}, }, "excludes": { Type: schema.TypeList, @@ -563,8 +562,7 @@ be executed directly, which will likely only succeed for scripts with shebang li Elem: &schema.Schema{ Type: schema.TypeString, }, - ConflictsWith: []string{"patch_config.0.windows_update.0.exclusive_patches"}, - AtLeastOneOf: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes", "patch_config.0.windows_update.0.exclusive_patches"}, + ExactlyOneOf: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes", "patch_config.0.windows_update.0.exclusive_patches"}, }, "exclusive_patches": { Type: schema.TypeList, @@ -575,8 +573,7 @@ This field must not be used with other patch configurations.`, Elem: &schema.Schema{ Type: schema.TypeString, }, - ConflictsWith: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes"}, - AtLeastOneOf: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes", "patch_config.0.windows_update.0.exclusive_patches"}, + ExactlyOneOf: []string{"patch_config.0.windows_update.0.classifications", "patch_config.0.windows_update.0.excludes", "patch_config.0.windows_update.0.exclusive_patches"}, }, }, }, diff --git a/google-beta/services/osconfig/resource_os_config_patch_deployment_generated_test.go b/google-beta/services/osconfig/resource_os_config_patch_deployment_generated_test.go index 4b859075bb..afa84a0e7a 100644 --- a/google-beta/services/osconfig/resource_os_config_patch_deployment_generated_test.go +++ b/google-beta/services/osconfig/resource_os_config_patch_deployment_generated_test.go @@ -305,7 +305,7 @@ resource "google_os_config_patch_deployment" "patch" { patch_config { mig_instances_allowed = true - + reboot_config = "ALWAYS" apt { @@ -329,7 +329,6 @@ resource "google_os_config_patch_deployment" "patch" { windows_update { classifications = ["CRITICAL", "SECURITY", "UPDATE"] - excludes = ["5012170"] } pre_step { diff --git a/google-beta/services/pubsub/resource_pubsub_schema_test.go b/google-beta/services/pubsub/resource_pubsub_schema_test.go index 2491bd8137..24e604984f 100644 --- a/google-beta/services/pubsub/resource_pubsub_schema_test.go +++ b/google-beta/services/pubsub/resource_pubsub_schema_test.go @@ -50,6 +50,17 @@ func testAccPubsubSchema_basic(schema string) string { type = "PROTOCOL_BUFFER" definition = "syntax = \"proto3\";\nmessage Results {\nstring message_request = 1;\nstring message_response = 2;\n}" } + + # Need to introduce delay for updates in order for tests to complete + # successfully due to caching effects. + resource "time_sleep" "wait_121_seconds" { + create_duration = "121s" + lifecycle { + replace_triggered_by = [ + google_pubsub_schema.foo + ] + } + } `, schema) } @@ -60,5 +71,16 @@ func testAccPubsubSchema_updated(schema string) string { type = "PROTOCOL_BUFFER" definition = "syntax = \"proto3\";\nmessage Results {\nstring message_request = 1;\nstring message_response = 2;\nstring timestamp_request = 3;\n}" } + + # Need to introduce delay for updates in order for tests to complete + # successfully due to caching effects. + resource "time_sleep" "wait_121_seconds" { + create_duration = "121s" + lifecycle { + replace_triggered_by = [ + google_pubsub_schema.foo + ] + } + } `, schema) } diff --git a/google-beta/services/secretmanager/resource_secret_manager_secret.go b/google-beta/services/secretmanager/resource_secret_manager_secret.go index f412d84757..2785b5d8e8 100644 --- a/google-beta/services/secretmanager/resource_secret_manager_secret.go +++ b/google-beta/services/secretmanager/resource_secret_manager_secret.go @@ -18,7 +18,6 @@ package secretmanager import ( - "context" "fmt" "log" "reflect" @@ -32,32 +31,6 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" ) -// Prevent ForceNew when upgrading replication.automatic -> replication.auto -func secretManagerSecretAutoCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { - oAutomatic, nAutomatic := diff.GetChange("replication.0.automatic") - _, nAuto := diff.GetChange("replication.0.auto") - autoLen := len(nAuto.([]interface{})) - - // Do not ForceNew if we are removing "automatic" while adding "auto" - if oAutomatic == true && nAutomatic == false && autoLen > 0 { - return nil - } - - if diff.HasChange("replication.0.automatic") { - if err := diff.ForceNew("replication.0.automatic"); err != nil { - return err - } - } - - if diff.HasChange("replication.0.auto") { - if err := diff.ForceNew("replication.0.auto"); err != nil { - return err - } - } - - return nil -} - func ResourceSecretManagerSecret() *schema.Resource { return &schema.Resource{ Create: resourceSecretManagerSecretCreate, @@ -76,7 +49,6 @@ func ResourceSecretManagerSecret() *schema.Resource { }, CustomizeDiff: customdiff.All( - secretManagerSecretAutoCustomizeDiff, tpgresource.SetLabelsDiff, tpgresource.SetAnnotationsDiff, tpgresource.DefaultProviderProject, diff --git a/google-beta/services/securitycenter/resource_scc_project_custom_module.go b/google-beta/services/securitycenter/resource_scc_project_custom_module.go deleted file mode 100644 index f156413fac..0000000000 --- a/google-beta/services/securitycenter/resource_scc_project_custom_module.go +++ /dev/null @@ -1,996 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// ---------------------------------------------------------------------------- -// -// *** 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 securitycenter - -import ( - "fmt" - "log" - "reflect" - "strings" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "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 ResourceSecurityCenterProjectCustomModule() *schema.Resource { - return &schema.Resource{ - Create: resourceSecurityCenterProjectCustomModuleCreate, - Read: resourceSecurityCenterProjectCustomModuleRead, - Update: resourceSecurityCenterProjectCustomModuleUpdate, - Delete: resourceSecurityCenterProjectCustomModuleDelete, - - Importer: &schema.ResourceImporter{ - State: resourceSecurityCenterProjectCustomModuleImport, - }, - - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(20 * time.Minute), - Update: schema.DefaultTimeout(20 * time.Minute), - Delete: schema.DefaultTimeout(20 * time.Minute), - }, - - CustomizeDiff: customdiff.All( - tpgresource.DefaultProviderProject, - ), - - Schema: map[string]*schema.Schema{ - "custom_config": { - Type: schema.TypeList, - Required: true, - Description: `The user specified custom configuration for the module.`, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "predicate": { - Type: schema.TypeList, - Required: true, - Description: `The CEL expression to evaluate to produce findings. When the expression evaluates -to true against a resource, a finding is generated.`, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "expression": { - Type: schema.TypeString, - Required: true, - Description: `Textual representation of an expression in Common Expression Language syntax.`, - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: `Description of the expression. This is a longer text which describes the -expression, e.g. when hovered over it in a UI.`, - }, - "location": { - Type: schema.TypeString, - Optional: true, - Description: `String indicating the location of the expression for error reporting, e.g. a -file name and a position in the file.`, - }, - "title": { - Type: schema.TypeString, - Optional: true, - Description: `Title for the expression, i.e. a short string describing its purpose. This can -be used e.g. in UIs which allow to enter the expression.`, - }, - }, - }, - }, - "recommendation": { - Type: schema.TypeString, - Required: true, - Description: `An explanation of the recommended steps that security teams can take to resolve -the detected issue. This explanation is returned with each finding generated by -this module in the nextSteps property of the finding JSON.`, - }, - "resource_selector": { - Type: schema.TypeList, - Required: true, - Description: `The resource types that the custom module operates on. Each custom module -can specify up to 5 resource types.`, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "resource_types": { - Type: schema.TypeList, - Required: true, - Description: `The resource types to run the detector on.`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - }, - "severity": { - Type: schema.TypeString, - Required: true, - ValidateFunc: verify.ValidateEnum([]string{"CRITICAL", "HIGH", "MEDIUM", "LOW"}), - Description: `The severity to assign to findings generated by the module. Possible values: ["CRITICAL", "HIGH", "MEDIUM", "LOW"]`, - }, - "custom_output": { - Type: schema.TypeList, - Optional: true, - Description: `Custom output properties.`, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "properties": { - Type: schema.TypeList, - Optional: true, - Description: `A list of custom output properties to add to the finding.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Optional: true, - Description: `Name of the property for the custom output.`, - }, - "value_expression": { - Type: schema.TypeList, - Optional: true, - Description: `The CEL expression for the custom output. A resource property can be specified -to return the value of the property or a text string enclosed in quotation marks.`, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "expression": { - Type: schema.TypeString, - Required: true, - Description: `Textual representation of an expression in Common Expression Language syntax.`, - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: `Description of the expression. This is a longer text which describes the -expression, e.g. when hovered over it in a UI.`, - }, - "location": { - Type: schema.TypeString, - Optional: true, - Description: `String indicating the location of the expression for error reporting, e.g. a -file name and a position in the file.`, - }, - "title": { - Type: schema.TypeString, - Optional: true, - Description: `Title for the expression, i.e. a short string describing its purpose. This can -be used e.g. in UIs which allow to enter the expression.`, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: `Text that describes the vulnerability or misconfiguration that the custom -module detects. This explanation is returned with each finding instance to -help investigators understand the detected issue. The text must be enclosed in quotation marks.`, - }, - }, - }, - }, - "display_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: verify.ValidateRegexp(`^[a-z][\w_]{0,127}$`), - Description: `The display name of the Security Health Analytics custom module. This -display name becomes the finding category for all findings that are -returned by this custom module. The display name must be between 1 and -128 characters, start with a lowercase letter, and contain alphanumeric -characters or underscores only.`, - }, - "enablement_state": { - Type: schema.TypeString, - Required: true, - ValidateFunc: verify.ValidateEnum([]string{"ENABLED", "DISABLED"}), - Description: `The enablement state of the custom module. Possible values: ["ENABLED", "DISABLED"]`, - }, - "ancestor_module": { - Type: schema.TypeString, - Computed: true, - Description: `If empty, indicates that the custom module was created in the organization,folder, -or project in which you are viewing the custom module. Otherwise, ancestor_module -specifies the organization or folder from which the custom module is inherited.`, - }, - "last_editor": { - Type: schema.TypeString, - Computed: true, - Description: `The editor that last updated the custom module.`, - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: `The resource name of the custom module. Its format is "projects/{project}/securityHealthAnalyticsSettings/customModules/{customModule}". -The id {customModule} is server-generated and is not user settable. It will be a numeric id containing 1-20 digits.`, - }, - "update_time": { - Type: schema.TypeString, - Computed: true, - Description: `The time at which the custom module was last updated. - -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".`, - }, - "project": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - }, - }, - UseJSONNumber: true, - } -} - -func resourceSecurityCenterProjectCustomModuleCreate(d *schema.ResourceData, meta interface{}) error { - config := meta.(*transport_tpg.Config) - userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) - if err != nil { - return err - } - - obj := make(map[string]interface{}) - displayNameProp, err := expandSecurityCenterProjectCustomModuleDisplayName(d.Get("display_name"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { - obj["displayName"] = displayNameProp - } - enablementStateProp, err := expandSecurityCenterProjectCustomModuleEnablementState(d.Get("enablement_state"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("enablement_state"); !tpgresource.IsEmptyValue(reflect.ValueOf(enablementStateProp)) && (ok || !reflect.DeepEqual(v, enablementStateProp)) { - obj["enablementState"] = enablementStateProp - } - customConfigProp, err := expandSecurityCenterProjectCustomModuleCustomConfig(d.Get("custom_config"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("custom_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(customConfigProp)) && (ok || !reflect.DeepEqual(v, customConfigProp)) { - obj["customConfig"] = customConfigProp - } - - lockName, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/securityHealthAnalyticsSettings/customModules") - if err != nil { - return err - } - transport_tpg.MutexStore.Lock(lockName) - defer transport_tpg.MutexStore.Unlock(lockName) - - url, err := tpgresource.ReplaceVars(d, config, "{{SecurityCenterBasePath}}projects/{{project}}/securityHealthAnalyticsSettings/customModules") - if err != nil { - return err - } - - log.Printf("[DEBUG] Creating new ProjectCustomModule: %#v", obj) - billingProject := "" - - project, err := tpgresource.GetProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectCustomModule: %s", err) - } - billingProject = project - - // err == nil indicates that the billing_project value was found - if bp, err := tpgresource.GetBillingProject(d, config); err == nil { - billingProject = bp - } - - res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "POST", - Project: billingProject, - RawURL: url, - UserAgent: userAgent, - Body: obj, - Timeout: d.Timeout(schema.TimeoutCreate), - }) - if err != nil { - return fmt.Errorf("Error creating ProjectCustomModule: %s", err) - } - if err := d.Set("name", flattenSecurityCenterProjectCustomModuleName(res["name"], d, config)); err != nil { - return fmt.Errorf(`Error setting computed identity field "name": %s`, err) - } - - // Store the ID now - id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}") - if err != nil { - return fmt.Errorf("Error constructing id: %s", err) - } - d.SetId(id) - - log.Printf("[DEBUG] Finished creating ProjectCustomModule %q: %#v", d.Id(), res) - - return resourceSecurityCenterProjectCustomModuleRead(d, meta) -} - -func resourceSecurityCenterProjectCustomModuleRead(d *schema.ResourceData, meta interface{}) error { - config := meta.(*transport_tpg.Config) - userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) - if err != nil { - return err - } - - url, err := tpgresource.ReplaceVars(d, config, "{{SecurityCenterBasePath}}projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}") - if err != nil { - return err - } - - billingProject := "" - - project, err := tpgresource.GetProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectCustomModule: %s", err) - } - billingProject = project - - // err == nil indicates that the billing_project value was found - if bp, err := tpgresource.GetBillingProject(d, config); err == nil { - billingProject = bp - } - - res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "GET", - Project: billingProject, - RawURL: url, - UserAgent: userAgent, - }) - if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("SecurityCenterProjectCustomModule %q", d.Id())) - } - - if err := d.Set("project", project); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - - if err := d.Set("name", flattenSecurityCenterProjectCustomModuleName(res["name"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - if err := d.Set("display_name", flattenSecurityCenterProjectCustomModuleDisplayName(res["displayName"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - if err := d.Set("enablement_state", flattenSecurityCenterProjectCustomModuleEnablementState(res["enablementState"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - if err := d.Set("update_time", flattenSecurityCenterProjectCustomModuleUpdateTime(res["updateTime"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - if err := d.Set("last_editor", flattenSecurityCenterProjectCustomModuleLastEditor(res["lastEditor"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - if err := d.Set("ancestor_module", flattenSecurityCenterProjectCustomModuleAncestorModule(res["ancestorModule"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - if err := d.Set("custom_config", flattenSecurityCenterProjectCustomModuleCustomConfig(res["customConfig"], d, config)); err != nil { - return fmt.Errorf("Error reading ProjectCustomModule: %s", err) - } - - return nil -} - -func resourceSecurityCenterProjectCustomModuleUpdate(d *schema.ResourceData, meta interface{}) error { - config := meta.(*transport_tpg.Config) - userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) - if err != nil { - return err - } - - billingProject := "" - - project, err := tpgresource.GetProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectCustomModule: %s", err) - } - billingProject = project - - obj := make(map[string]interface{}) - enablementStateProp, err := expandSecurityCenterProjectCustomModuleEnablementState(d.Get("enablement_state"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("enablement_state"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enablementStateProp)) { - obj["enablementState"] = enablementStateProp - } - customConfigProp, err := expandSecurityCenterProjectCustomModuleCustomConfig(d.Get("custom_config"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("custom_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, customConfigProp)) { - obj["customConfig"] = customConfigProp - } - - lockName, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/securityHealthAnalyticsSettings/customModules") - if err != nil { - return err - } - transport_tpg.MutexStore.Lock(lockName) - defer transport_tpg.MutexStore.Unlock(lockName) - - url, err := tpgresource.ReplaceVars(d, config, "{{SecurityCenterBasePath}}projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}") - if err != nil { - return err - } - - log.Printf("[DEBUG] Updating ProjectCustomModule %q: %#v", d.Id(), obj) - updateMask := []string{} - - if d.HasChange("enablement_state") { - updateMask = append(updateMask, "enablementState") - } - - if d.HasChange("custom_config") { - updateMask = append(updateMask, "customConfig") - } - // 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, ",")}) - if err != nil { - return err - } - - // err == nil indicates that the billing_project value was found - if bp, err := tpgresource.GetBillingProject(d, config); err == nil { - billingProject = bp - } - - res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "PATCH", - Project: billingProject, - RawURL: url, - UserAgent: userAgent, - Body: obj, - Timeout: d.Timeout(schema.TimeoutUpdate), - }) - - if err != nil { - return fmt.Errorf("Error updating ProjectCustomModule %q: %s", d.Id(), err) - } else { - log.Printf("[DEBUG] Finished updating ProjectCustomModule %q: %#v", d.Id(), res) - } - - return resourceSecurityCenterProjectCustomModuleRead(d, meta) -} - -func resourceSecurityCenterProjectCustomModuleDelete(d *schema.ResourceData, meta interface{}) error { - config := meta.(*transport_tpg.Config) - userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) - if err != nil { - return err - } - - billingProject := "" - - project, err := tpgresource.GetProject(d, config) - if err != nil { - return fmt.Errorf("Error fetching project for ProjectCustomModule: %s", err) - } - billingProject = project - - lockName, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/securityHealthAnalyticsSettings/customModules") - if err != nil { - return err - } - transport_tpg.MutexStore.Lock(lockName) - defer transport_tpg.MutexStore.Unlock(lockName) - - url, err := tpgresource.ReplaceVars(d, config, "{{SecurityCenterBasePath}}projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}") - if err != nil { - return err - } - - var obj map[string]interface{} - log.Printf("[DEBUG] Deleting ProjectCustomModule %q", d.Id()) - - // err == nil indicates that the billing_project value was found - if bp, err := tpgresource.GetBillingProject(d, config); err == nil { - billingProject = bp - } - - res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "DELETE", - Project: billingProject, - RawURL: url, - UserAgent: userAgent, - Body: obj, - Timeout: d.Timeout(schema.TimeoutDelete), - }) - if err != nil { - return transport_tpg.HandleNotFoundError(err, d, "ProjectCustomModule") - } - - log.Printf("[DEBUG] Finished deleting ProjectCustomModule %q: %#v", d.Id(), res) - return nil -} - -func resourceSecurityCenterProjectCustomModuleImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - config := meta.(*transport_tpg.Config) - if err := tpgresource.ParseImportId([]string{ - "projects/(?P[^/]+)/securityHealthAnalyticsSettings/customModules/(?P[^/]+)", - "(?P[^/]+)/(?P[^/]+)", - "(?P[^/]+)", - }, d, config); err != nil { - return nil, err - } - - // Replace import id for the resource id - id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}") - if err != nil { - return nil, fmt.Errorf("Error constructing id: %s", err) - } - d.SetId(id) - - return []*schema.ResourceData{d}, nil -} - -func flattenSecurityCenterProjectCustomModuleName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return v - } - return tpgresource.NameFromSelfLinkStateFunc(v) -} - -func flattenSecurityCenterProjectCustomModuleDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleEnablementState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleLastEditor(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleAncestorModule(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return nil - } - original := v.(map[string]interface{}) - if len(original) == 0 { - return nil - } - transformed := make(map[string]interface{}) - transformed["predicate"] = - flattenSecurityCenterProjectCustomModuleCustomConfigPredicate(original["predicate"], d, config) - transformed["custom_output"] = - flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutput(original["customOutput"], d, config) - transformed["resource_selector"] = - flattenSecurityCenterProjectCustomModuleCustomConfigResourceSelector(original["resourceSelector"], d, config) - transformed["severity"] = - flattenSecurityCenterProjectCustomModuleCustomConfigSeverity(original["severity"], d, config) - transformed["description"] = - flattenSecurityCenterProjectCustomModuleCustomConfigDescription(original["description"], d, config) - transformed["recommendation"] = - flattenSecurityCenterProjectCustomModuleCustomConfigRecommendation(original["recommendation"], d, config) - return []interface{}{transformed} -} -func flattenSecurityCenterProjectCustomModuleCustomConfigPredicate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return nil - } - original := v.(map[string]interface{}) - if len(original) == 0 { - return nil - } - transformed := make(map[string]interface{}) - transformed["expression"] = - flattenSecurityCenterProjectCustomModuleCustomConfigPredicateExpression(original["expression"], d, config) - transformed["title"] = - flattenSecurityCenterProjectCustomModuleCustomConfigPredicateTitle(original["title"], d, config) - transformed["description"] = - flattenSecurityCenterProjectCustomModuleCustomConfigPredicateDescription(original["description"], d, config) - transformed["location"] = - flattenSecurityCenterProjectCustomModuleCustomConfigPredicateLocation(original["location"], d, config) - return []interface{}{transformed} -} -func flattenSecurityCenterProjectCustomModuleCustomConfigPredicateExpression(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigPredicateTitle(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigPredicateDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigPredicateLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutput(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return nil - } - original := v.(map[string]interface{}) - if len(original) == 0 { - return nil - } - transformed := make(map[string]interface{}) - transformed["properties"] = - flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputProperties(original["properties"], d, config) - return []interface{}{transformed} -} -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputProperties(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return v - } - l := v.([]interface{}) - transformed := make([]interface{}, 0, len(l)) - for _, raw := range l { - original := raw.(map[string]interface{}) - if len(original) < 1 { - // Do not include empty json objects coming back from the api - continue - } - transformed = append(transformed, map[string]interface{}{ - "name": flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesName(original["name"], d, config), - "value_expression": flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpression(original["valueExpression"], d, config), - }) - } - return transformed -} -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpression(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return nil - } - original := v.(map[string]interface{}) - if len(original) == 0 { - return nil - } - transformed := make(map[string]interface{}) - transformed["expression"] = - flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionExpression(original["expression"], d, config) - transformed["title"] = - flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionTitle(original["title"], d, config) - transformed["description"] = - flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionDescription(original["description"], d, config) - transformed["location"] = - flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionLocation(original["location"], d, config) - return []interface{}{transformed} -} -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionExpression(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionTitle(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigResourceSelector(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return nil - } - original := v.(map[string]interface{}) - if len(original) == 0 { - return nil - } - transformed := make(map[string]interface{}) - transformed["resource_types"] = - flattenSecurityCenterProjectCustomModuleCustomConfigResourceSelectorResourceTypes(original["resourceTypes"], d, config) - return []interface{}{transformed} -} -func flattenSecurityCenterProjectCustomModuleCustomConfigResourceSelectorResourceTypes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigSeverity(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecurityCenterProjectCustomModuleCustomConfigRecommendation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func expandSecurityCenterProjectCustomModuleDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleEnablementState(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - if len(l) == 0 || l[0] == nil { - return nil, nil - } - raw := l[0] - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedPredicate, err := expandSecurityCenterProjectCustomModuleCustomConfigPredicate(original["predicate"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedPredicate); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["predicate"] = transformedPredicate - } - - transformedCustomOutput, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutput(original["custom_output"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedCustomOutput); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["customOutput"] = transformedCustomOutput - } - - transformedResourceSelector, err := expandSecurityCenterProjectCustomModuleCustomConfigResourceSelector(original["resource_selector"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedResourceSelector); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["resourceSelector"] = transformedResourceSelector - } - - transformedSeverity, err := expandSecurityCenterProjectCustomModuleCustomConfigSeverity(original["severity"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedSeverity); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["severity"] = transformedSeverity - } - - transformedDescription, err := expandSecurityCenterProjectCustomModuleCustomConfigDescription(original["description"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedDescription); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["description"] = transformedDescription - } - - transformedRecommendation, err := expandSecurityCenterProjectCustomModuleCustomConfigRecommendation(original["recommendation"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedRecommendation); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["recommendation"] = transformedRecommendation - } - - return transformed, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigPredicate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - if len(l) == 0 || l[0] == nil { - return nil, nil - } - raw := l[0] - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedExpression, err := expandSecurityCenterProjectCustomModuleCustomConfigPredicateExpression(original["expression"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedExpression); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["expression"] = transformedExpression - } - - transformedTitle, err := expandSecurityCenterProjectCustomModuleCustomConfigPredicateTitle(original["title"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedTitle); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["title"] = transformedTitle - } - - transformedDescription, err := expandSecurityCenterProjectCustomModuleCustomConfigPredicateDescription(original["description"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedDescription); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["description"] = transformedDescription - } - - transformedLocation, err := expandSecurityCenterProjectCustomModuleCustomConfigPredicateLocation(original["location"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedLocation); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["location"] = transformedLocation - } - - return transformed, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigPredicateExpression(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigPredicateTitle(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigPredicateDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigPredicateLocation(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutput(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - if len(l) == 0 || l[0] == nil { - return nil, nil - } - raw := l[0] - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedProperties, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputProperties(original["properties"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedProperties); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["properties"] = transformedProperties - } - - return transformed, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputProperties(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - req := make([]interface{}, 0, len(l)) - for _, raw := range l { - if raw == nil { - continue - } - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedName, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesName(original["name"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedName); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["name"] = transformedName - } - - transformedValueExpression, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpression(original["value_expression"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedValueExpression); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["valueExpression"] = transformedValueExpression - } - - req = append(req, transformed) - } - return req, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpression(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - if len(l) == 0 || l[0] == nil { - return nil, nil - } - raw := l[0] - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedExpression, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionExpression(original["expression"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedExpression); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["expression"] = transformedExpression - } - - transformedTitle, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionTitle(original["title"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedTitle); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["title"] = transformedTitle - } - - transformedDescription, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionDescription(original["description"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedDescription); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["description"] = transformedDescription - } - - transformedLocation, err := expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionLocation(original["location"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedLocation); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["location"] = transformedLocation - } - - return transformed, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionExpression(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionTitle(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigCustomOutputPropertiesValueExpressionLocation(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigResourceSelector(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - if len(l) == 0 || l[0] == nil { - return nil, nil - } - raw := l[0] - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedResourceTypes, err := expandSecurityCenterProjectCustomModuleCustomConfigResourceSelectorResourceTypes(original["resource_types"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedResourceTypes); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["resourceTypes"] = transformedResourceTypes - } - - return transformed, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigResourceSelectorResourceTypes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigSeverity(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecurityCenterProjectCustomModuleCustomConfigRecommendation(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} diff --git a/google-beta/services/securitycenter/resource_scc_project_custom_module_generated_test.go b/google-beta/services/securitycenter/resource_scc_project_custom_module_generated_test.go deleted file mode 100644 index 8cbbcd8181..0000000000 --- a/google-beta/services/securitycenter/resource_scc_project_custom_module_generated_test.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// ---------------------------------------------------------------------------- -// -// *** 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 securitycenter_test - -import ( - "fmt" - "strings" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" - transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" -) - -func TestAccSecurityCenterProjectCustomModule_sccProjectCustomModuleBasicExample(t *testing.T) { - t.Parallel() - - context := map[string]interface{}{ - "random_suffix": acctest.RandString(t, 10), - } - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckSecurityCenterProjectCustomModuleDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleBasicExample(context), - }, - { - ResourceName: "google_scc_project_custom_module.example", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleBasicExample(context map[string]interface{}) string { - return acctest.Nprintf(` -resource "google_scc_project_custom_module" "example" { - display_name = "basic_custom_module" - enablement_state = "ENABLED" - custom_config { - predicate { - expression = "resource.rotationPeriod > duration(\"2592000s\")" - } - resource_selector { - resource_types = [ - "cloudkms.googleapis.com/CryptoKey", - ] - } - description = "The rotation period of the identified cryptokey resource exceeds 30 days." - recommendation = "Set the rotation period to at most 30 days." - severity = "MEDIUM" - } -} -`, context) -} - -func TestAccSecurityCenterProjectCustomModule_sccProjectCustomModuleFullExample(t *testing.T) { - t.Parallel() - - context := map[string]interface{}{ - "random_suffix": acctest.RandString(t, 10), - } - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckSecurityCenterProjectCustomModuleDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleFullExample(context), - }, - { - ResourceName: "google_scc_project_custom_module.example", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleFullExample(context map[string]interface{}) string { - return acctest.Nprintf(` -resource "google_scc_project_custom_module" "example" { - display_name = "full_custom_module" - enablement_state = "ENABLED" - custom_config { - predicate { - expression = "resource.rotationPeriod > duration(\"2592000s\")" - title = "Purpose of the expression" - description = "description of the expression" - location = "location of the expression" - } - custom_output { - properties { - name = "duration" - value_expression { - expression = "resource.rotationPeriod" - title = "Purpose of the expression" - description = "description of the expression" - location = "location of the expression" - } - } - } - resource_selector { - resource_types = [ - "cloudkms.googleapis.com/CryptoKey", - ] - } - severity = "LOW" - description = "Description of the custom module" - recommendation = "Steps to resolve violation" - } -} -`, context) -} - -func testAccCheckSecurityCenterProjectCustomModuleDestroyProducer(t *testing.T) func(s *terraform.State) error { - return func(s *terraform.State) error { - for name, rs := range s.RootModule().Resources { - if rs.Type != "google_scc_project_custom_module" { - continue - } - if strings.HasPrefix(name, "data.") { - continue - } - - config := acctest.GoogleProviderConfig(t) - - url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{SecurityCenterBasePath}}projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}") - if err != nil { - return err - } - - billingProject := "" - - if config.BillingProject != "" { - billingProject = config.BillingProject - } - - _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "GET", - Project: billingProject, - RawURL: url, - UserAgent: config.UserAgent, - }) - if err == nil { - return fmt.Errorf("SecurityCenterProjectCustomModule still exists at %s", url) - } - } - - return nil - } -} diff --git a/google-beta/services/securitycenter/resource_scc_project_custom_module_sweeper.go b/google-beta/services/securitycenter/resource_scc_project_custom_module_sweeper.go deleted file mode 100644 index ea52538328..0000000000 --- a/google-beta/services/securitycenter/resource_scc_project_custom_module_sweeper.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// ---------------------------------------------------------------------------- -// -// *** 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 securitycenter - -import ( - "context" - "log" - "strings" - "testing" - - "github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/sweeper" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" - transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" -) - -func init() { - sweeper.AddTestSweepers("SecurityCenterProjectCustomModule", testSweepSecurityCenterProjectCustomModule) -} - -// At the time of writing, the CI only passes us-central1 as the region -func testSweepSecurityCenterProjectCustomModule(region string) error { - resourceName := "SecurityCenterProjectCustomModule" - log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) - - config, err := sweeper.SharedConfigForRegion(region) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) - return err - } - - err = config.LoadAndValidate(context.Background()) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) - return err - } - - t := &testing.T{} - billingId := envvar.GetTestBillingAccountFromEnv(t) - - // Setup variables to replace in list template - d := &tpgresource.ResourceDataMock{ - FieldsInSchema: map[string]interface{}{ - "project": config.Project, - "region": region, - "location": region, - "zone": "-", - "billing_account": billingId, - }, - } - - listTemplate := strings.Split("https://securitycenter.googleapis.com/v1/projects/{{project}}/securityHealthAnalyticsSettings/customModules", "?")[0] - listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) - return nil - } - - res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "GET", - Project: config.Project, - RawURL: listUrl, - UserAgent: config.UserAgent, - }) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) - return nil - } - - resourceList, ok := res["projectCustomModules"] - if !ok { - log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") - return nil - } - - rl := resourceList.([]interface{}) - - log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) - // Keep count of items that aren't sweepable for logging. - nonPrefixCount := 0 - for _, ri := range rl { - obj := ri.(map[string]interface{}) - if obj["name"] == nil { - log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) - return nil - } - - name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) - // Skip resources that shouldn't be sweeped - if !sweeper.IsSweepableTestResource(name) { - nonPrefixCount++ - continue - } - - deleteTemplate := "https://securitycenter.googleapis.com/v1/projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}" - deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) - return nil - } - deleteUrl = deleteUrl + name - - // Don't wait on operations as we may have a lot to delete - _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ - Config: config, - Method: "DELETE", - Project: config.Project, - RawURL: deleteUrl, - UserAgent: config.UserAgent, - }) - if err != nil { - log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) - } else { - log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) - } - } - - if nonPrefixCount > 0 { - log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) - } - - return nil -} diff --git a/google-beta/services/securitycenter/resource_scc_project_custom_module_test.go b/google-beta/services/securitycenter/resource_scc_project_custom_module_test.go deleted file mode 100644 index 89478babbc..0000000000 --- a/google-beta/services/securitycenter/resource_scc_project_custom_module_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 -package securitycenter_test - -import ( - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" -) - -func TestAccSecurityCenterProjectCustomModule_sccProjectCustomModuleUpdate(t *testing.T) { - t.Parallel() - - context := map[string]interface{}{ - "random_suffix": acctest.RandString(t, 10), - } - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckSecurityCenterProjectCustomModuleDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleFullExample(context), - }, - { - ResourceName: "google_scc_project_custom_module.example", - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleUpdate(context), - }, - { - ResourceName: "google_scc_project_custom_module.example", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccSecurityCenterProjectCustomModule_sccProjectCustomModuleUpdate(context map[string]interface{}) string { - return acctest.Nprintf(` -resource "google_scc_project_custom_module" "example" { - display_name = "full_custom_module" - enablement_state = "DISABLED" - custom_config { - predicate { - expression = "resource.name == \"updated-name\"" - title = "Updated expression title" - description = "Updated description of the expression" - location = "Updated location of the expression" - } - custom_output { - properties { - name = "violation" - value_expression { - expression = "resource.name" - title = "Updated expression title" - description = "Updated description of the expression" - location = "Updated location of the expression" - } - } - } - resource_selector { - resource_types = [ - "compute.googleapis.com/Instance", - ] - } - severity = "CRITICAL" - description = "Updated description of the custom module" - recommendation = "Updated steps to resolve violation" - } -} -`, context) -} diff --git a/website/docs/d/certificate_manager_certificate_map.html.markdown b/website/docs/d/certificate_manager_certificate_map.html.markdown deleted file mode 100644 index 20e2e4fe5b..0000000000 --- a/website/docs/d/certificate_manager_certificate_map.html.markdown +++ /dev/null @@ -1,30 +0,0 @@ ---- -subcategory: "Certificate manager" -description: |- - Contains the data that describes a Certificate Map ---- -# google_certificate_manager_certificate_map - -Get info about a Google Certificate Manager Certificate Map resource. - -## Example Usage - -```tf -data "google_certificate_manager_certificate_map" "default" { - name = "cert-map" -} -``` - -## Argument Reference - -The following arguments are supported: - -* `name` - (Required) The name of the certificate map. - -- - - -* `project` - (Optional) The ID of the project in which the resource belongs. If it - is not provided, the provider project is used. - -## Attributes Reference - -See [google_certificate_manager_certificate_map](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/certificate_manager_certificate_map) resource for details of the available attributes. diff --git a/website/docs/d/compute_instance_template.html.markdown b/website/docs/d/compute_instance_template.html.markdown index e771c3be87..2af65eaae6 100644 --- a/website/docs/d/compute_instance_template.html.markdown +++ b/website/docs/d/compute_instance_template.html.markdown @@ -6,8 +6,6 @@ description: |- # google\_compute\_instance\_template --> **Note**: Global instance templates can be used in any region. To lower the impact of outages outside your region and gain data residency within your region, use [google_compute_region_instance_template](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_region_instance_template). - Get information about a VM instance template resource within GCE. For more information see [the official documentation](https://cloud.google.com/compute/docs/instance-templates) and diff --git a/website/docs/guides/version_5_upgrade.html.markdown b/website/docs/guides/version_5_upgrade.html.markdown index 3845211cd3..d3fb8647f9 100644 --- a/website/docs/guides/version_5_upgrade.html.markdown +++ b/website/docs/guides/version_5_upgrade.html.markdown @@ -525,9 +525,3 @@ resource "google_secret_manager_secret" "my-secret" { ### `google_identity_platform_project_default_config` has been removed from the provider Use the `google_identity_platform_config` resource instead. It contains a more comprehensive list of fields, and was created before `google_identity_platform_project_default_config` was added. - -## Resource: `google_compute_service_attachment` - -### `reconcile_connections` now defaults from API - -`reconcile_connections` previously defaults to true. Now it will default from the API. diff --git a/website/docs/r/compute_instance_template.html.markdown b/website/docs/r/compute_instance_template.html.markdown index c04c64137d..2d08f340fb 100644 --- a/website/docs/r/compute_instance_template.html.markdown +++ b/website/docs/r/compute_instance_template.html.markdown @@ -6,8 +6,6 @@ description: |- # google\_compute\_instance\_template --> **Note**: Global instance templates can be used in any region. To lower the impact of outages outside your region and gain data residency within your region, use [google_compute_region_instance_template](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_region_instance_template). - Manages a VM instance template resource within GCE. For more information see [the official documentation](https://cloud.google.com/compute/docs/instance-templates) and diff --git a/website/docs/r/os_config_patch_deployment.html.markdown b/website/docs/r/os_config_patch_deployment.html.markdown index 82f064b83d..00e4fd37c1 100644 --- a/website/docs/r/os_config_patch_deployment.html.markdown +++ b/website/docs/r/os_config_patch_deployment.html.markdown @@ -206,7 +206,7 @@ resource "google_os_config_patch_deployment" "patch" { patch_config { mig_instances_allowed = true - + reboot_config = "ALWAYS" apt { @@ -230,7 +230,6 @@ resource "google_os_config_patch_deployment" "patch" { windows_update { classifications = ["CRITICAL", "SECURITY", "UPDATE"] - excludes = ["5012170"] } pre_step { diff --git a/website/docs/r/scc_project_custom_module.html.markdown b/website/docs/r/scc_project_custom_module.html.markdown deleted file mode 100644 index 0b6ce94fb6..0000000000 --- a/website/docs/r/scc_project_custom_module.html.markdown +++ /dev/null @@ -1,288 +0,0 @@ ---- -# ---------------------------------------------------------------------------- -# -# *** 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. -# -# ---------------------------------------------------------------------------- -subcategory: "Security Command Center (SCC)" -description: |- - Represents an instance of a Security Health Analytics custom module, including - its full module name, display name, enablement state, and last updated time. ---- - -# google\_scc\_project\_custom\_module - -Represents an instance of a Security Health Analytics custom module, including -its full module name, display name, enablement state, and last updated time. -You can create a custom module at the organization, folder, or project level. -Custom modules that you create at the organization or folder level are inherited -by the child folders and projects. - - -To get more information about ProjectCustomModule, see: - -* [API documentation](https://cloud.google.com/security-command-center/docs/reference/rest/v1/projects.securityHealthAnalyticsSettings.customModules) -* How-to Guides - * [Overview of custom modules for Security Health Analytics](https://cloud.google.com/security-command-center/docs/custom-modules-sha-overview) - - -## Example Usage - Scc Project Custom Module Basic - - -```hcl -resource "google_scc_project_custom_module" "example" { - display_name = "basic_custom_module" - enablement_state = "ENABLED" - custom_config { - predicate { - expression = "resource.rotationPeriod > duration(\"2592000s\")" - } - resource_selector { - resource_types = [ - "cloudkms.googleapis.com/CryptoKey", - ] - } - description = "The rotation period of the identified cryptokey resource exceeds 30 days." - recommendation = "Set the rotation period to at most 30 days." - severity = "MEDIUM" - } -} -``` - -## Example Usage - Scc Project Custom Module Full - - -```hcl -resource "google_scc_project_custom_module" "example" { - display_name = "full_custom_module" - enablement_state = "ENABLED" - custom_config { - predicate { - expression = "resource.rotationPeriod > duration(\"2592000s\")" - title = "Purpose of the expression" - description = "description of the expression" - location = "location of the expression" - } - custom_output { - properties { - name = "duration" - value_expression { - expression = "resource.rotationPeriod" - title = "Purpose of the expression" - description = "description of the expression" - location = "location of the expression" - } - } - } - resource_selector { - resource_types = [ - "cloudkms.googleapis.com/CryptoKey", - ] - } - severity = "LOW" - description = "Description of the custom module" - recommendation = "Steps to resolve violation" - } -} -``` - -## Argument Reference - -The following arguments are supported: - - -* `display_name` - - (Required) - The display name of the Security Health Analytics custom module. This - display name becomes the finding category for all findings that are - returned by this custom module. The display name must be between 1 and - 128 characters, start with a lowercase letter, and contain alphanumeric - characters or underscores only. - -* `enablement_state` - - (Required) - The enablement state of the custom module. - Possible values are: `ENABLED`, `DISABLED`. - -* `custom_config` - - (Required) - The user specified custom configuration for the module. - Structure is [documented below](#nested_custom_config). - - -The `custom_config` block supports: - -* `predicate` - - (Required) - The CEL expression to evaluate to produce findings. When the expression evaluates - to true against a resource, a finding is generated. - Structure is [documented below](#nested_predicate). - -* `custom_output` - - (Optional) - Custom output properties. - Structure is [documented below](#nested_custom_output). - -* `resource_selector` - - (Required) - The resource types that the custom module operates on. Each custom module - can specify up to 5 resource types. - Structure is [documented below](#nested_resource_selector). - -* `severity` - - (Required) - The severity to assign to findings generated by the module. - Possible values are: `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`. - -* `description` - - (Optional) - Text that describes the vulnerability or misconfiguration that the custom - module detects. This explanation is returned with each finding instance to - help investigators understand the detected issue. The text must be enclosed in quotation marks. - -* `recommendation` - - (Required) - An explanation of the recommended steps that security teams can take to resolve - the detected issue. This explanation is returned with each finding generated by - this module in the nextSteps property of the finding JSON. - - -The `predicate` block supports: - -* `expression` - - (Required) - Textual representation of an expression in Common Expression Language syntax. - -* `title` - - (Optional) - Title for the expression, i.e. a short string describing its purpose. This can - be used e.g. in UIs which allow to enter the expression. - -* `description` - - (Optional) - Description of the expression. This is a longer text which describes the - expression, e.g. when hovered over it in a UI. - -* `location` - - (Optional) - String indicating the location of the expression for error reporting, e.g. a - file name and a position in the file. - -The `custom_output` block supports: - -* `properties` - - (Optional) - A list of custom output properties to add to the finding. - Structure is [documented below](#nested_properties). - - -The `properties` block supports: - -* `name` - - (Optional) - Name of the property for the custom output. - -* `value_expression` - - (Optional) - The CEL expression for the custom output. A resource property can be specified - to return the value of the property or a text string enclosed in quotation marks. - Structure is [documented below](#nested_value_expression). - - -The `value_expression` block supports: - -* `expression` - - (Required) - Textual representation of an expression in Common Expression Language syntax. - -* `title` - - (Optional) - Title for the expression, i.e. a short string describing its purpose. This can - be used e.g. in UIs which allow to enter the expression. - -* `description` - - (Optional) - Description of the expression. This is a longer text which describes the - expression, e.g. when hovered over it in a UI. - -* `location` - - (Optional) - String indicating the location of the expression for error reporting, e.g. a - file name and a position in the file. - -The `resource_selector` block supports: - -* `resource_types` - - (Required) - The resource types to run the detector on. - -- - - - - -* `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: - -* `id` - an identifier for the resource with format `projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}}` - -* `name` - - The resource name of the custom module. Its format is "projects/{project}/securityHealthAnalyticsSettings/customModules/{customModule}". - The id {customModule} is server-generated and is not user settable. It will be a numeric id containing 1-20 digits. - -* `update_time` - - The time at which the custom module was last updated. - 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". - -* `last_editor` - - The editor that last updated the custom module. - -* `ancestor_module` - - If empty, indicates that the custom module was created in the organization,folder, - or project in which you are viewing the custom module. Otherwise, ancestor_module - specifies the organization or folder from which the custom module is inherited. - - -## Timeouts - -This resource provides the following -[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: - -- `create` - Default is 20 minutes. -- `update` - Default is 20 minutes. -- `delete` - Default is 20 minutes. - -## Import - - -ProjectCustomModule can be imported using any of these accepted formats: - -``` -$ terraform import google_scc_project_custom_module.default projects/{{project}}/securityHealthAnalyticsSettings/customModules/{{name}} -$ terraform import google_scc_project_custom_module.default {{project}}/{{name}} -$ terraform import google_scc_project_custom_module.default {{name}} -``` - -## User Project Overrides - -This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override).