From e8ce2704f144a22bb6915919f2326ca1a282e870 Mon Sep 17 00:00:00 2001 From: Whitney Smith Date: Mon, 24 Jul 2023 22:10:39 +0000 Subject: [PATCH] test: add testing for gcp org account mapping --- .../main.tf | 7 +- .../main.tf | 4 +- .../main.tf | 152 ++++++++++++++++++ ...gration_aws_org_agentless_scanning_test.go | 1 - ...integration_gcp_agentless_scanning_test.go | 47 ++++++ lacework/account_mapping_helper.go | 5 - ..._integration_aws_org_agentless_scanning.go | 2 +- ...work_integration_gcp_agentless_scanning.go | 54 +++---- 8 files changed, 235 insertions(+), 37 deletions(-) create mode 100644 examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf diff --git a/examples/resource_lacework_integration_aws_org_agentless_scanning/main.tf b/examples/resource_lacework_integration_aws_org_agentless_scanning/main.tf index b76a6f7ab..2833a604e 100644 --- a/examples/resource_lacework_integration_aws_org_agentless_scanning/main.tf +++ b/examples/resource_lacework_integration_aws_org_agentless_scanning/main.tf @@ -13,7 +13,7 @@ provider "lacework" { resource "lacework_integration_aws_org_agentless_scanning" "example" { name = var.name query_text = var.query_text - scan_frequency = 24 + scan_frequency = var.scan_frequency scan_containers = true scan_host_vulnerabilities = true scan_multi_volume = false @@ -50,6 +50,11 @@ variable "account_id" { default = "" } +variable "scan_frequency" { + type = number + default = 24 +} + variable "bucket_arn" { type = string default = "" diff --git a/examples/resource_lacework_integration_gcp_agentless_scanning/main.tf b/examples/resource_lacework_integration_gcp_agentless_scanning/main.tf index afb04b770..ae85c9758 100644 --- a/examples/resource_lacework_integration_gcp_agentless_scanning/main.tf +++ b/examples/resource_lacework_integration_gcp_agentless_scanning/main.tf @@ -38,7 +38,7 @@ variable "token_uri" { variable "integration_type" { type = string - default = "PROJECT" + default = "ORGANIZATION" } variable "project_id" { @@ -75,7 +75,7 @@ resource "lacework_integration_gcp_agentless_scanning" "example" { private_key = var.private_key token_uri = var.token_uri } - resource_level = "PROJECT" + resource_level = "ORGANIZATION" resource_id = "techally-test" bucket_name = var.bucket_name scanning_project_id = "gcp-lw-scanner" diff --git a/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf b/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf new file mode 100644 index 000000000..b50fabedb --- /dev/null +++ b/examples/resource_lacework_integration_gcp_org_agentless_scanning/main.tf @@ -0,0 +1,152 @@ +terraform { + required_providers { + lacework = { + source = "lacework/lacework" + } + } +} + +provider "lacework" { + organization = true +} + +variable "integration_name" { + type = string + default = "GCP Agentless Scanning Example" +} + +variable "client_id" { + type = string + default = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +} + +variable "client_email" { + type = string + default = "email@some-project-name.iam.gserviceaccount.com" +} + +variable "private_key_id" { + type = string + default = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +} + +variable "private_key" { + type = string + default = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +} + +variable "token_uri" { + type = string + default = "https://oauth2.googleapis.com/token" +} + +variable "integration_type" { + type = string + default = "PROJECT" +} + +variable "project_id" { + type = string + default = "example-project-id" +} + +variable "bucket_name" { + type = string + default = "storage bucket id" +} + +variable "scanning_project_id" { + type = string + default = "scanning-project-id" +} + +variable "query_text" { + type = string + default = "" +} + +variable "filter_list" { + type = list(string) + default = ["proj1", "proj2"] +} + +variable "org_account_mappings" { + type = list(object({ + default_lacework_account = string + mapping = list(object({ + lacework_account = string + aws_accounts = list(string) + })) + })) + default = [] + description = "Mapping of GCP projects to Lacework accounts within a Lacework organization" +} + +resource "lacework_integration_gcp_agentless_scanning" "example" { + name = var.integration_name + credentials { + client_id = var.client_id + client_email = var.client_email + private_key_id = var.private_key_id + private_key = var.private_key + token_uri = var.token_uri + } + resource_level = "ORGANIZATION" + resource_id = "techally-test" + bucket_name = var.bucket_name + scanning_project_id = "gcp-lw-scanner" + scan_frequency = 24 + 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 + +dynamic "org_account_mappings" { + for_each = var.org_account_mappings + content { + default_lacework_account = org_account_mappings.value["default_lacework_account"] + + dynamic "mapping" { + for_each = org_account_mappings.value["mapping"] + content { + lacework_account = mapping.value["lacework_account"] + gcp_projects = mapping.value["gcp_projects"] + } + } + } + } +} + +output "name" { + value = lacework_integration_gcp_agentless_scanning.example.name +} + +output "client_id" { + value = lacework_integration_gcp_agentless_scanning.example.credentials[0].client_id +} + +output "client_email" { + value = lacework_integration_gcp_agentless_scanning.example.credentials[0].client_email +} + +output "bucket_name" { + value = lacework_integration_gcp_agentless_scanning.example.bucket_name +} + +output "scanning_project_id" { + value = lacework_integration_gcp_agentless_scanning.example.scanning_project_id +} + +output "scan_frequency" { + value = lacework_integration_gcp_agentless_scanning.example.scan_frequency +} + +output "server_token" { + value = lacework_integration_gcp_agentless_scanning.example.server_token +} + +output "org_account_mappings" { + value = lacework_integration_gcp_agentless_scanning.example.org_account_mappings +} \ No newline at end of file diff --git a/integration/resource_lacework_integration_aws_org_agentless_scanning_test.go b/integration/resource_lacework_integration_aws_org_agentless_scanning_test.go index 9bf573115..5e571bae4 100644 --- a/integration/resource_lacework_integration_aws_org_agentless_scanning_test.go +++ b/integration/resource_lacework_integration_aws_org_agentless_scanning_test.go @@ -40,7 +40,6 @@ func TestIntegrationAwsOrgAgentlessScanningLog(t *testing.T) { // Create new AWS Agentless Scanning Integration create := terraform.InitAndApplyAndIdempotent(t, terraformOptions) createData := GetAwsAgentlessOrgScanningResponse(create) - println(create) actualName := terraform.Output(t, terraformOptions, "name") assert.Equal( t, diff --git a/integration/resource_lacework_integration_gcp_agentless_scanning_test.go b/integration/resource_lacework_integration_gcp_agentless_scanning_test.go index 8586f214e..3971587aa 100644 --- a/integration/resource_lacework_integration_gcp_agentless_scanning_test.go +++ b/integration/resource_lacework_integration_gcp_agentless_scanning_test.go @@ -47,3 +47,50 @@ func TestIntegrationGcpAgentlessScanningCreate(t *testing.T) { 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) + fmt.Println(gcreds, integration_name, update_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{}{ + "integration_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, + "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) + } +} diff --git a/lacework/account_mapping_helper.go b/lacework/account_mapping_helper.go index ef19efe0b..e717575b1 100644 --- a/lacework/account_mapping_helper.go +++ b/lacework/account_mapping_helper.go @@ -13,11 +13,6 @@ func (f *accountMappingsFile) Empty() bool { return f.DefaultLaceworkAccount == "" } -type typeStruct struct { - awsAccounts string - gcpProjects string -} - var awsMappingType string = "aws_accounts" var gcpMappingType string = "gcp_projects" diff --git a/lacework/resource_lacework_integration_aws_org_agentless_scanning.go b/lacework/resource_lacework_integration_aws_org_agentless_scanning.go index 43d31a073..a12ac1b57 100644 --- a/lacework/resource_lacework_integration_aws_org_agentless_scanning.go +++ b/lacework/resource_lacework_integration_aws_org_agentless_scanning.go @@ -175,7 +175,7 @@ var awsOrgAgentlessScanningIntegrationSchema = map[string]*schema.Schema{ "lacework_account": { Type: schema.TypeString, Required: true, - Description: "The Lacework account name where the CloudTrail activity from the selected AWS accounts will appear.", + Description: "The Lacework account name where the Agentless activity from the selected AWS accounts will appear.", }, "aws_accounts": { Type: schema.TypeSet, diff --git a/lacework/resource_lacework_integration_gcp_agentless_scanning.go b/lacework/resource_lacework_integration_gcp_agentless_scanning.go index ebd59c2d1..6f521a434 100644 --- a/lacework/resource_lacework_integration_gcp_agentless_scanning.go +++ b/lacework/resource_lacework_integration_gcp_agentless_scanning.go @@ -212,31 +212,31 @@ func resourceLaceworkIntegrationGcpAgentlessScanning() *schema.Resource { "org_account_mappings": { Type: schema.TypeList, Optional: true, - Description: "Mapping of AWS accounts to Lacework accounts within a Lacework organization.", + 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 AWS account will appear", + Description: "The default Lacework account name where any non-mapped GCP project will appear", }, "mapping": { Type: schema.TypeSet, Required: true, - Description: "A map of AWS accounts to Lacework account. This can be specified multiple times to map multiple Lacework accounts.", + 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 CloudTrail activity from the selected AWS accounts will appear.", + Description: "The Lacework account name where the Agentless activity from the selected gcp projects will appear.", }, - "aws_accounts": { + "gcp_projects": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, MinItems: 1, Required: true, - Description: "The list of AWS account IDs to map.", + Description: "The list of GCP project IDs to map.", }, }, }, @@ -341,27 +341,6 @@ func resourceLaceworkIntegrationGcpAgentlessScanningCreate(d *schema.ResourceDat d.Set("server_token", integration.ServerToken) d.Set("uri", integration.Uri) - accountMapFileBytes, err := integration.Data.DecodeAccountMappingFile() - if err != nil { - return resource.NonRetryableError(err) - } - - accountMapFile := new(accountMappingsFile) - if len(accountMapFileBytes) != 0 { - // The integration has an account mapping file - // unmarshal its content into the account mapping struct - err := json.Unmarshal(accountMapFileBytes, accountMapFile) - if err != nil { - return resource.NonRetryableError(fmt.Errorf("Error decoding organization account mapping: %s", err)) - } - - } - - err = d.Set("org_account_mappings", flattenOrgAccountMappings(accountMapFile, gcpMappingType)) - if err != nil { - return resource.NonRetryableError(fmt.Errorf("Error flattening organization account mapping: %s", err)) - } - log.Printf("[INFO] Created %s integration with guid: %v\n", api.GcpSidekickCloudAccount.String(), integration.IntgGuid) return nil @@ -413,6 +392,27 @@ func resourceLaceworkIntegrationGcpAgentlessScanningRead(d *schema.ResourceData, d.Set("filter_list", trimmed_filter_list) } + accountMapFileBytes, err := integration.Data.DecodeAccountMappingFile() + if err != nil { + return err + } + + accountMapFile := new(accountMappingsFile) + if len(accountMapFileBytes) != 0 { + // The integration has an account mapping file + // unmarshal its content into the account mapping struct + err := json.Unmarshal(accountMapFileBytes, accountMapFile) + if err != nil { + return fmt.Errorf("Error decoding organization account mapping: %s", err) + } + + } + + err = d.Set("org_account_mappings", flattenOrgAccountMappings(accountMapFile, gcpMappingType)) + if err != nil { + return fmt.Errorf("Error flattening organization account mapping: %s", err) + } + log.Printf("[INFO] Read %s integration with guid: %v\n", api.GcpSidekickCloudAccount.String(), integration.IntgGuid) return nil