From 56f08f1dd99a2247b3ca7fc2aaa9f26ecec5fd9d Mon Sep 17 00:00:00 2001 From: Whitney Smith Date: Fri, 11 Aug 2023 16:34:28 +0000 Subject: [PATCH] chore: create org specific integration test --- .../main.tf | 41 +- ...integration_gcp_agentless_scanning_test.go | 65 +-- ...gration_gcp_org_agentless_scanning_test.go | 72 +++ lacework/account_mapping_helper.go | 52 +- ...work_integration_gcp_agentless_scanning.go | 443 +++++++++--------- 5 files changed, 350 insertions(+), 323 deletions(-) create mode 100644 integration/resource_lacework_integration_gcp_org_agentless_scanning_test.go diff --git a/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf b/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf index 20a042bb..25281ea3 100644 --- a/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf +++ b/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf @@ -7,12 +7,12 @@ terraform { } provider "lacework" { - organization = true + organization = true } -variable "name" { +variable "lacework_integration_name" { type = string - default = "GCP Agentless Scanning org_example" + default = "GCP Agentless Scanning Example" } variable "client_id" { @@ -47,7 +47,7 @@ variable "integration_type" { variable "project_id" { type = string - default = "org-example-project-id" + default = "example-project-id" } variable "bucket_name" { @@ -55,7 +55,7 @@ variable "bucket_name" { default = "storage bucket id" } -variable "scanning_project_id" { +variable "scanning-project-id" { type = string default = "scanning-project-id" } @@ -70,11 +70,6 @@ variable "filter_list" { default = ["proj1", "proj2"] } -variable "scan_frequency" { - type = number - default = 24 -} - variable "org_account_mappings" { type = list(object({ default_lacework_account = string @@ -88,7 +83,7 @@ variable "org_account_mappings" { } resource "lacework_integration_gcp_agentless_scanning" "org_example" { - name = var.name + name = var.lacework_integration_name credentials { client_id = var.client_id client_email = var.client_email @@ -99,12 +94,6 @@ resource "lacework_integration_gcp_agentless_scanning" "org_example" { resource_level = "ORGANIZATION" resource_id = "techally-test" bucket_name = var.bucket_name - scanning_project_id = "gcp-lw-scanner" - scan_frequency = var.scan_frequency - scan_containers = true - scan_host_vulnerabilities = true - scan_multi_volume = false - scan_stopped_instances = true query_text = var.query_text filter_list = var.filter_list @@ -125,33 +114,29 @@ resource "lacework_integration_gcp_agentless_scanning" "org_example" { } output "name" { - value = lacework_integration_gcp_agentless_scanning.org_example.name + value = lacework_integration_gcp_agentless_scanning.example.name } output "client_id" { - value = lacework_integration_gcp_agentless_scanning.org_example.credentials[0].client_id + value = lacework_integration_gcp_agentless_scanning.example.credentials[0].client_id } output "client_email" { - value = lacework_integration_gcp_agentless_scanning.org_example.credentials[0].client_email + value = lacework_integration_gcp_agentless_scanning.example.credentials[0].client_email } output "bucket_name" { - value = lacework_integration_gcp_agentless_scanning.org_example.bucket_name + value = lacework_integration_gcp_agentless_scanning.example.bucket_name } output "scanning_project_id" { - value = lacework_integration_gcp_agentless_scanning.org_example.scanning_project_id + value = lacework_integration_gcp_agentless_scanning.example.scanning_project_id } output "scan_frequency" { - value = lacework_integration_gcp_agentless_scanning.org_example.scan_frequency + value = lacework_integration_gcp_agentless_scanning.example.scan_frequency } output "server_token" { - value = lacework_integration_gcp_agentless_scanning.org_example.server_token + value = lacework_integration_gcp_agentless_scanning.example.server_token } - -output "org_account_mappings" { - value = lacework_integration_gcp_agentless_scanning.org_example.org_account_mappings -} \ No newline at end of file diff --git a/integration/resource_lacework_integration_gcp_agentless_scanning_test.go b/integration/resource_lacework_integration_gcp_agentless_scanning_test.go index 4300229a..698aceac 100644 --- a/integration/resource_lacework_integration_gcp_agentless_scanning_test.go +++ b/integration/resource_lacework_integration_gcp_agentless_scanning_test.go @@ -20,58 +20,12 @@ func TestIntegrationGcpAgentlessScanningCreate(t *testing.T) { if assert.Nil(t, err, "this test requires you to set GOOGLE_CREDENTIALS environment variable") { terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ TerraformDir: "../examples/resource_lacework_integration_gcp_agentless_scanning", - Vars: map[string]interface{}{ - "integration_name": integration_name, - "client_id": gcreds.ClientID, - "client_email": gcreds.ClientEmail, - "private_key_id": gcreds.PrivateKeyID, - "bucket_name": "storage bucket id", - }, - EnvVars: map[string]string{ - "TF_VAR_private_key": gcreds.PrivateKey, - "LW_API_TOKEN": LwApiToken, - }, - }) - defer terraform.Destroy(t, terraformOptions) - - // Create new Google Agentless Scanning integration - create := terraform.InitAndApplyAndIdempotent(t, terraformOptions) - createData := GetGcpAgentlessScanningResponse(create) - assert.Equal(t, integration_name, createData.Data.Name) - - // Update Gcp integration - terraformOptions.Vars["integration_name"] = update_integration_name - - update := terraform.ApplyAndIdempotent(t, terraformOptions) - updateData := GetGcpAgentlessScanningResponse(update) - assert.Equal(t, update_integration_name, updateData.Data.Name) - } -} - -func TestIntegrationGcpAgentlessOrgScanningCreate(t *testing.T) { - gcreds, err := googleLoadDefaultCredentials() - integration_name := "GCP Agentless Scanning Example Integration Test" - update_integration_name := fmt.Sprintf("%s Updated", integration_name) - if assert.Nil(t, err, "this test requires you to set GOOGLE_CREDENTIALS environment variable") { - terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ - TerraformDir: "../examples/resource_lacework_integration_gcp_org_agentless_scanning", Vars: map[string]interface{}{ "name": integration_name, "client_id": gcreds.ClientID, "client_email": gcreds.ClientEmail, "private_key_id": gcreds.PrivateKeyID, "bucket_name": "storage bucket id", - "org_account_mappings": []map[string]interface{}{ - { - "default_lacework_account": "customerdemo", - "mapping": []map[string]interface{}{ - { - "lacework_account": "abc", - "gcp_projects": []string{"lw-scanner-5"}, - }, - }, - }, - }, }, EnvVars: map[string]string{ "TF_VAR_private_key": gcreds.PrivateKey, @@ -86,24 +40,7 @@ func TestIntegrationGcpAgentlessOrgScanningCreate(t *testing.T) { assert.Equal(t, integration_name, createData.Data.Name) // Update Gcp integration - terraformOptions.Vars = map[string]interface{}{ - "name": update_integration_name, - "client_id": gcreds.ClientID, - "client_email": gcreds.ClientEmail, - "private_key_id": gcreds.PrivateKeyID, - "bucket_name": "storage bucket id", - "org_account_mappings": []map[string]interface{}{ - { - "default_lacework_account": "customerdemo", - "mapping": []map[string]interface{}{ - { - "lacework_account": "abc", - "gcp_projects": []string{"lw-scanner-5"}, - }, - }, - }, - }, - } + terraformOptions.Vars["integration_name"] = update_integration_name update := terraform.ApplyAndIdempotent(t, terraformOptions) updateData := GetGcpAgentlessScanningResponse(update) diff --git a/integration/resource_lacework_integration_gcp_org_agentless_scanning_test.go b/integration/resource_lacework_integration_gcp_org_agentless_scanning_test.go new file mode 100644 index 00000000..e5b826ec --- /dev/null +++ b/integration/resource_lacework_integration_gcp_org_agentless_scanning_test.go @@ -0,0 +1,72 @@ +package integration + +import ( + "fmt" + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/stretchr/testify/assert" +) + +func TestIntegrationGcpAgentlessOrgScanningCreateAndUpdate(t *testing.T) { + gcreds, err := googleLoadDefaultCredentials() + integration_name := "GCP Org Agentless Scanning Example Integration Test" + update_integration_name := fmt.Sprintf("%s Updated", integration_name) + if assert.Nil(t, err, "this test requires you to set GOOGLE_CREDENTIALS environment variable") { + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: "../examples/resource_lacework_integration_gcp_org_agentless_scanning", + Vars: map[string]interface{}{ + "name": integration_name, + "client_id": gcreds.ClientID, + "client_email": gcreds.ClientEmail, + "private_key_id": gcreds.PrivateKeyID, + "bucket_name": "storage bucket id", + "org_account_mappings": []map[string]interface{}{ + { + "default_lacework_account": "customerdemo", + "mapping": []map[string]interface{}{ + { + "lacework_account": "abc", + "gcp_projects": []string{"techally-test"}, + }, + }, + }, + }, + }, + EnvVars: map[string]string{ + "TF_VAR_private_key": gcreds.PrivateKey, + "LW_API_TOKEN": LwApiToken, + }, + }) + defer terraform.Destroy(t, terraformOptions) + + // Create new Google Agentless Scanning integration + create := terraform.InitAndApplyAndIdempotent(t, terraformOptions) + createData := GetGcpAgentlessScanningResponse(create) + assert.Equal(t, integration_name, createData.Data.Name) + + // Update Gcp integration + terraformOptions.Vars = map[string]interface{}{ + "name": update_integration_name, + "client_id": gcreds.ClientID, + "client_email": gcreds.ClientEmail, + "private_key_id": gcreds.PrivateKeyID, + "bucket_name": "storage bucket id", + "org_account_mappings": []map[string]interface{}{ + { + "default_lacework_account": "customerdemo", + "mapping": []map[string]interface{}{ + { + "lacework_account": "abc", + "gcp_projects": []string{"techally-test"}, + }, + }, + }, + }, + } + + update := terraform.ApplyAndIdempotent(t, terraformOptions) + updateData := GetGcpAgentlessScanningResponse(update) + assert.Equal(t, update_integration_name, updateData.Data.Name) + } +} diff --git a/lacework/account_mapping_helper.go b/lacework/account_mapping_helper.go index e717575b..344b24d6 100644 --- a/lacework/account_mapping_helper.go +++ b/lacework/account_mapping_helper.go @@ -5,7 +5,7 @@ import ( ) type accountMappingsFile struct { - DefaultLaceworkAccount string `json:"defaultLaceworkAccountAws"` + DefaultLaceworkAccount string `json:"defaultLaceworkAccount"` Mappings map[string]interface{} `json:"integration_mappings"` } @@ -58,21 +58,57 @@ func flattenOrgAccountMappings(mappingFile *accountMappingsFile, mappingsType st func flattenMappings(mappings map[string]interface{}, mappingsType string) *schema.Set { var ( - orgAccountMappingsSchema = awsCloudTrailIntegrationSchema["org_account_mappings"].Elem.(*schema.Resource) - mappingSchema = orgAccountMappingsSchema.Schema["mapping"].Elem.(*schema.Resource) - accountsSchema = mappingSchema.Schema[mappingsType].Elem.(*schema.Schema) - res = schema.NewSet(schema.HashResource(mappingSchema), []interface{}{}) + awsOrgAccountMappingsSchema = awsCloudTrailIntegrationSchema["org_account_mappings"].Elem.(*schema.Resource) + awsMappingSchema = awsOrgAccountMappingsSchema.Schema["mapping"].Elem.(*schema.Resource) + awsAccountsSchema = awsMappingSchema.Schema[mappingsType].Elem.(*schema.Schema) + awsRes = schema.NewSet(schema.HashResource(awsMappingSchema), []interface{}{}) ) for laceworkAccount, m := range mappings { mappingValue := m.(map[string]interface{}) - res.Add(map[string]interface{}{ + awsRes.Add(map[string]interface{}{ "lacework_account": laceworkAccount, - mappingsType: schema.NewSet(schema.HashSchema(accountsSchema), + mappingsType: schema.NewSet(schema.HashSchema(awsAccountsSchema), mappingValue[mappingsType].([]interface{}), ), }) } - return res + return awsRes +} + +func flattenOrgGcpAccountMappings(mappingFile *accountMappingsFile, mappingsType string) []map[string]interface{} { + orgAccMappings := make([]map[string]interface{}, 0, 1) + + if mappingFile.Empty() { + return orgAccMappings + } + + mappings := map[string]interface{}{ + "default_lacework_account": mappingFile.DefaultLaceworkAccount, + "mapping": flattenGcpMappings(mappingFile.Mappings, mappingsType), + } + + orgAccMappings = append(orgAccMappings, mappings) + return orgAccMappings +} + +func flattenGcpMappings(mappings map[string]interface{}, mappingsType string) *schema.Set { + var ( + gcpOrgAccountMappingsSchema = gcpAgentlessScanningIntegrationSchema["org_account_mappings"].Elem.(*schema.Resource) + gcpMappingSchema = gcpOrgAccountMappingsSchema.Schema["mapping"].Elem.(*schema.Resource) + gcpAccountsSchema = gcpMappingSchema.Schema[mappingsType].Elem.(*schema.Schema) + gcpRes = schema.NewSet(schema.HashResource(gcpMappingSchema), []interface{}{}) + ) + + for laceworkAccount, m := range mappings { + mappingValue := m.(map[string]interface{}) + gcpRes.Add(map[string]interface{}{ + "lacework_account": laceworkAccount, + mappingsType: schema.NewSet(schema.HashSchema(gcpAccountsSchema), + mappingValue[mappingsType].([]interface{}), + ), + }) + } + return gcpRes } diff --git a/lacework/resource_lacework_integration_gcp_agentless_scanning.go b/lacework/resource_lacework_integration_gcp_agentless_scanning.go index 6f521a43..90da8940 100644 --- a/lacework/resource_lacework_integration_gcp_agentless_scanning.go +++ b/lacework/resource_lacework_integration_gcp_agentless_scanning.go @@ -19,233 +19,233 @@ func resourceLaceworkIntegrationGcpAgentlessScanning() *schema.Resource { Read: resourceLaceworkIntegrationGcpAgentlessScanningRead, Update: resourceLaceworkIntegrationGcpAgentlessScanningUpdate, Delete: resourceLaceworkIntegrationGcpAgentlessScanningDelete, - + Schema: gcpAgentlessScanningIntegrationSchema, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, + } +} - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "The integration name.", - }, - "intg_guid": { - Type: schema.TypeString, - Computed: true, - }, - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "The state of the external integration.", - }, - "retries": { - Type: schema.TypeInt, - Optional: true, - Default: 5, - Description: "The number of attempts to create the external integration.", - }, - "credentials": { - Type: schema.TypeList, - MaxItems: 1, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Required: true, - Description: "Client Id from credentials file.", - }, - "private_key_id": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - return !d.HasChanges( - "name", "resource_level", "resource_id", "org_level", "enabled", - "credentials.0.client_id", - "credentials.0.client_email", - ) - }, - Description: "Private Key Id from credentials file.", - }, - "client_email": { - Type: schema.TypeString, - Required: true, - Description: "Client email from credentials file.", - }, - "private_key": { - Type: schema.TypeString, - Required: true, - Sensitive: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // @afiune we can't compare this element since our API, for security reasons, - // does NOT return the private key configured in the Lacework server. So if - // any other element changed from the credentials then we trigger a diff - return !d.HasChanges( - "name", "resource_level", "resource_id", "org_level", "enabled", - "credentials.0.client_id", - "credentials.0.client_email", - ) - }, - Description: "Private Key from credentials file.", - }, - "token_uri": { - Type: schema.TypeString, - Optional: true, - Default: "https://oauth2.googleapis.com/token", - Description: "Token URI from credentials file.", - }, +var gcpAgentlessScanningIntegrationSchema = map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "The integration name.", + }, + "intg_guid": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "The state of the external integration.", + }, + "retries": { + Type: schema.TypeInt, + Optional: true, + Default: 5, + Description: "The number of attempts to create the external integration.", + }, + "credentials": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + Description: "Client Id from credentials file.", + }, + "private_key_id": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return !d.HasChanges( + "name", "resource_level", "resource_id", "org_level", "enabled", + "credentials.0.client_id", + "credentials.0.client_email", + ) }, + Description: "Private Key Id from credentials file.", }, - }, - "resource_level": { - Type: schema.TypeString, - Optional: true, - Default: api.GcpProjectIntegration.String(), - StateFunc: func(val interface{}) string { - return strings.ToUpper(val.(string)) + "client_email": { + Type: schema.TypeString, + Required: true, + Description: "Client email from credentials file.", }, - ValidateFunc: func(value interface{}, key string) ([]string, []error) { - switch strings.ToUpper(value.(string)) { - case api.GcpProjectIntegration.String(), - api.GcpOrganizationIntegration.String(): - return nil, nil - default: - return nil, []error{ - fmt.Errorf("%s: can only be either '%s' or '%s'", - key, - api.GcpProjectIntegration.String(), - api.GcpOrganizationIntegration.String()), - } - } + "private_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // @afiune we can't compare this element since our API, for security reasons, + // does NOT return the private key configured in the Lacework server. So if + // any other element changed from the credentials then we trigger a diff + return !d.HasChanges( + "name", "resource_level", "resource_id", "org_level", "enabled", + "credentials.0.client_id", + "credentials.0.client_email", + ) + }, + Description: "Private Key from credentials file.", + }, + "token_uri": { + Type: schema.TypeString, + Optional: true, + Default: "https://oauth2.googleapis.com/token", + Description: "Token URI from credentials file.", }, - Description: "Integration level - ORGANIZATION / PROJECT.", - }, - "resource_id": { - Type: schema.TypeString, - Required: true, - Description: "Organization Id or Project Id.", - }, - "created_or_updated_time": { - Type: schema.TypeString, - Computed: true, - }, - "created_or_updated_by": { - Type: schema.TypeString, - Computed: true, - }, - "type_name": { - Type: schema.TypeString, - Computed: true, - }, - "org_level": { - Type: schema.TypeBool, - Computed: true, - }, - "server_token": { - Type: schema.TypeString, - Computed: true, - }, - "uri": { - Type: schema.TypeString, - Computed: true, - }, - "bucket_name": { - Type: schema.TypeString, - Required: true, - Description: "Bucket containing analysis results shared with Lacework platform.", - }, - "scanning_project_id": { - Type: schema.TypeString, - Required: true, - Description: "Project ID where scanner is deployed.", - }, - "scan_frequency": { - Type: schema.TypeInt, - Optional: true, - Default: 24, - Description: "How often in hours the scan will run in hours.", - }, - "scan_containers": { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Whether to includes scanning for containers.", - }, - "scan_host_vulnerabilities": { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Whether to includes scanning for host vulnerabilities.", - }, - "scan_multi_volume": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether to scan secondary volumes (true) or only root volumes (false)", - }, - "scan_stopped_instances": { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Whether to scan stopped instances (true)", }, - "query_text": { - Type: schema.TypeString, - Optional: true, - Default: "", - Description: "The LQL query text.", + }, + }, + "resource_level": { + Type: schema.TypeString, + Optional: true, + Default: api.GcpProjectIntegration.String(), + StateFunc: func(val interface{}) string { + return strings.ToUpper(val.(string)) + }, + ValidateFunc: func(value interface{}, key string) ([]string, []error) { + switch strings.ToUpper(value.(string)) { + case api.GcpProjectIntegration.String(), + api.GcpOrganizationIntegration.String(): + return nil, nil + default: + return nil, []error{ + fmt.Errorf("%s: can only be either '%s' or '%s'", + key, + api.GcpProjectIntegration.String(), + api.GcpOrganizationIntegration.String()), + } + } + }, + Description: "Integration level - ORGANIZATION / PROJECT.", + }, + "resource_id": { + Type: schema.TypeString, + Required: true, + Description: "Organization Id or Project Id.", + }, + "created_or_updated_time": { + Type: schema.TypeString, + Computed: true, + }, + "created_or_updated_by": { + Type: schema.TypeString, + Computed: true, + }, + "type_name": { + Type: schema.TypeString, + Computed: true, + }, + "org_level": { + Type: schema.TypeBool, + Computed: true, + }, + "server_token": { + Type: schema.TypeString, + Computed: true, + }, + "uri": { + Type: schema.TypeString, + Computed: true, + }, + "bucket_name": { + Type: schema.TypeString, + Required: true, + Description: "Bucket containing analysis results shared with Lacework platform.", + }, + "scanning_project_id": { + Type: schema.TypeString, + Required: true, + Description: "Project ID where scanner is deployed.", + }, + "scan_frequency": { + Type: schema.TypeInt, + Optional: true, + Default: 24, + Description: "How often in hours the scan will run in hours.", + }, + "scan_containers": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Whether to includes scanning for containers.", + }, + "scan_host_vulnerabilities": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Whether to includes scanning for host vulnerabilities.", + }, + "scan_multi_volume": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether to scan secondary volumes (true) or only root volumes (false)", + }, + "scan_stopped_instances": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Whether to scan stopped instances (true)", + }, + "query_text": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "The LQL query text.", + }, + "filter_list": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + StateFunc: func(val interface{}) string { + return strings.TrimSpace(val.(string)) }, - "filter_list": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - StateFunc: func(val interface{}) string { - return strings.TrimSpace(val.(string)) - }, + }, + Default: nil, + Description: "List of Projects to specifically include/exclude.", + }, + "org_account_mappings": { + Type: schema.TypeList, + Optional: true, + Description: "Mapping of GCP projects to Lacework accounts within a Lacework organization.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_lacework_account": { + Type: schema.TypeString, + Required: true, + Description: "The default Lacework account name where any non-mapped GCP project will appear", }, - Default: nil, - Description: "List of Projects to specifically include/exclude.", - }, - "org_account_mappings": { - Type: schema.TypeList, - Optional: true, - Description: "Mapping of GCP projects to Lacework accounts within a Lacework organization.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "default_lacework_account": { - Type: schema.TypeString, - Required: true, - Description: "The default Lacework account name where any non-mapped GCP project will appear", - }, - "mapping": { - Type: schema.TypeSet, - Required: true, - Description: "A map of GCP projects to Lacework account. This can be specified multiple times to map multiple Lacework accounts.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "lacework_account": { - Type: schema.TypeString, - Required: true, - Description: "The Lacework account name where the Agentless activity from the selected gcp projects will appear.", - }, - "gcp_projects": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - MinItems: 1, - Required: true, - Description: "The list of GCP project IDs to map.", - }, - }, + "mapping": { + Type: schema.TypeSet, + Required: true, + Description: "A map of GCP projects to Lacework account. This can be specified multiple times to map multiple Lacework accounts.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lacework_account": { + Type: schema.TypeString, + Required: true, + Description: "The Lacework account name where the Agentless activity from the selected gcp projects will appear.", + }, + "gcp_projects": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + MinItems: 1, + Required: true, + Description: "The list of GCP project IDs to map.", }, }, }, }, }, }, - } + }, } func resourceLaceworkIntegrationGcpAgentlessScanningCreate(d *schema.ResourceData, meta interface{}) error { @@ -255,11 +255,10 @@ func resourceLaceworkIntegrationGcpAgentlessScanningCreate(d *schema.ResourceDat resourceLevel = api.GcpProjectIntegration ) - if strings.ToUpper( - d.Get("resource_level").(string), - ) == api.GcpOrganizationIntegration.String() { + if strings.ToUpper(d.Get("resource_level").(string)) == api.GcpOrganizationIntegration.String() { resourceLevel = api.GcpOrganizationIntegration } + log.Printf("[INFO] Creating %s integration\n", api.GcpSidekickCloudAccount.String()) gcpSidekickData := api.GcpSidekickData{ @@ -284,16 +283,14 @@ func resourceLaceworkIntegrationGcpAgentlessScanningCreate(d *schema.ResourceDat } // verify if the user provided an account mapping - if d.Get("resource_level") == api.GcpOrganizationIntegration { - accountMapFile := getResourceOrgAccountMappings(d, gcpMappingType) - if !accountMapFile.Empty() { - accountMapFileBytes, err := json.Marshal(accountMapFile) - if err != nil { - return err - } - - gcpSidekickData.EncodeAccountMappingFile(accountMapFileBytes) + accountMapFile := getResourceOrgAccountMappings(d, gcpMappingType) + if !accountMapFile.Empty() { + accountMapFileBytes, err := json.Marshal(accountMapFile) + if err != nil { + return err } + + gcpSidekickData.EncodeAccountMappingFile(accountMapFileBytes) } data := api.NewCloudAccount(d.Get("name").(string), @@ -408,7 +405,7 @@ func resourceLaceworkIntegrationGcpAgentlessScanningRead(d *schema.ResourceData, } - err = d.Set("org_account_mappings", flattenOrgAccountMappings(accountMapFile, gcpMappingType)) + err = d.Set("org_account_mappings", flattenOrgGcpAccountMappings(accountMapFile, gcpMappingType)) if err != nil { return fmt.Errorf("Error flattening organization account mapping: %s", err) }