Skip to content

Commit

Permalink
test: add testing for gcp org account mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
wl-smith committed Aug 14, 2023
1 parent 135ffc6 commit 0844bca
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -50,6 +50,11 @@ variable "account_id" {
default = ""
}

variable "scan_frequency" {
type = number
default = 24
}

variable "bucket_arn" {
type = string
default = ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
terraform {
required_providers {
lacework = {
source = "lacework/lacework"
}
}
}

provider "lacework" {
organization = true
}

variable "name" {
type = string
default = "GCP Agentless Scanning org_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 = "org-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 "scan_frequency" {
type = number
default = 24
}

variable "org_account_mappings" {
type = list(object({
default_lacework_account = string
mapping = list(object({
lacework_account = string
gcp_projects = list(string)
}))
}))
default = []
description = "Mapping of GCP projects to Lacework accounts within a Lacework organization"
}

resource "lacework_integration_gcp_agentless_scanning" "org_example" {
name = var.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 = 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

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.org_example.name
}

output "client_id" {
value = lacework_integration_gcp_agentless_scanning.org_example.credentials[0].client_id
}

output "client_email" {
value = lacework_integration_gcp_agentless_scanning.org_example.credentials[0].client_email
}

output "bucket_name" {
value = lacework_integration_gcp_agentless_scanning.org_example.bucket_name
}

output "scanning_project_id" {
value = lacework_integration_gcp_agentless_scanning.org_example.scanning_project_id
}

output "scan_frequency" {
value = lacework_integration_gcp_agentless_scanning.org_example.scan_frequency
}

output "server_token" {
value = lacework_integration_gcp_agentless_scanning.org_example.server_token
}

output "org_account_mappings" {
value = lacework_integration_gcp_agentless_scanning.org_example.org_account_mappings
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,66 @@ 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)
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,
"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{"lw-scanner-5"},
},
},
},
},
}

update := terraform.ApplyAndIdempotent(t, terraformOptions)
updateData := GetGcpAgentlessScanningResponse(update)
assert.Equal(t, update_integration_name, updateData.Data.Name)
}
}
5 changes: 0 additions & 5 deletions lacework/account_mapping_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
54 changes: 27 additions & 27 deletions lacework/resource_lacework_integration_gcp_agentless_scanning.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
},
},
},
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0844bca

Please sign in to comment.