Skip to content

Commit 152359d

Browse files
authored
feat(GROW-2949): Provide organization_id for project level agentless integration (#1648)
* feat(GROW-2949): Provide organization_id for project level integration Signed-off-by: Lei Jin <[email protected]> * feat: remove restriction on org level integration Signed-off-by: Lei Jin <[email protected]> * feat: Require org_id for gcp agentless integration Signed-off-by: Lei Jin <[email protected]> --------- Signed-off-by: Lei Jin <[email protected]>
1 parent cbe5213 commit 152359d

File tree

8 files changed

+87
-25
lines changed

8 files changed

+87
-25
lines changed

cli/cdk/go/proto/v1/cdk.pb.go

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/cdk/go/proto/v1/cdk_grpc.pb.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/cmd/generate_gcp.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ func initGenerateGcpTfCommandFlags() {
315315
&GenerateGcpCommandState.GcpOrganizationId,
316316
"organization_id",
317317
"",
318-
"specify the organization id (only set if organization_integration is set)")
318+
"specify the organization id (only set if agentless integration or organization_integration is set)")
319319
generateGcpTfCommand.PersistentFlags().StringVar(
320320
&GenerateGcpCommandState.GcpProjectId,
321321
"project_id",
@@ -736,9 +736,17 @@ func promptGcpGenerate(
736736
Prompt: &survey.Confirm{Message: QuestionGcpOrganizationIntegration, Default: config.OrganizationIntegration},
737737
Response: &config.OrganizationIntegration,
738738
},
739+
}); err != nil {
740+
return err
741+
}
742+
743+
organizationIdRequired := config.Agentless || config.OrganizationIntegration
744+
745+
if err := SurveyMultipleQuestionWithValidation(
746+
[]SurveyQuestionWithValidationArgs{
739747
{
740748
Prompt: &survey.Input{Message: QuestionGcpOrganizationID, Default: config.GcpOrganizationId},
741-
Checks: []*bool{&config.OrganizationIntegration},
749+
Checks: []*bool{&organizationIdRequired},
742750
Required: true,
743751
Response: &config.GcpOrganizationId,
744752
},

cli/docs/lacework_generate_cloud-account_gcp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ lacework generate cloud-account gcp [flags]
5858
-h, --help help for gcp
5959
--include_root_projects Disables logic that includes root-level projects if excluding folders (default true)
6060
--k8s_filter filter out GKE logs from GCP Audit Log sinks (default true)
61-
--organization_id string specify the organization id (only set if organization_integration is set)
61+
--organization_id string specify the organization id (only set if agentless integration or organization_integration is set)
6262
--organization_integration enable organization integration
6363
--output string location to write generated content (default is ~/lacework/gcp)
6464
--prefix string prefix that will be used at the beginning of every generated resource

integration/gcp_generation_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,48 @@ func TestGenerationGcpAgentless(t *testing.T) {
121121
assert.Equal(t, buildTf, tfResult)
122122
}
123123

124+
// Test Agentless only generation
125+
func TestGenerationGcpAgentlessProjectLevel(t *testing.T) {
126+
os.Setenv("LW_NOCACHE", "true")
127+
defer os.Setenv("LW_NOCACHE", "")
128+
var final string
129+
130+
tfResult := runGcpGenerateTest(t,
131+
func(c *expect.Console) {
132+
expectsCliOutput(t, c, []MsgRspHandler{
133+
MsgRsp{cmd.QuestionGcpEnableAgentless, "y"},
134+
MsgRsp{cmd.QuestionGcpEnableConfiguration, "n"},
135+
MsgRsp{cmd.QuestionGcpEnableAuditLog, "n"},
136+
MsgRsp{cmd.QuestionGcpProjectID, projectId},
137+
MsgRsp{cmd.QuestionGcpRegions, "us-east1"},
138+
MsgRsp{cmd.QuestionGcpOrganizationIntegration, "n"},
139+
MsgRsp{cmd.QuestionGcpOrganizationID, organizationId},
140+
MsgRsp{cmd.QuestionGcpConfigureAdvanced, "y"},
141+
MsgMenu{cmd.GcpAdvancedOptAgentless, 0},
142+
MsgRsp{cmd.QuestionGcpProjectFilterList, "p1,p2"},
143+
MsgRsp{cmd.QuestionGcpAnotherAdvancedOpt, "n"},
144+
MsgRsp{cmd.QuestionRunTfPlan, "n"},
145+
})
146+
147+
final, _ = c.ExpectEOF()
148+
},
149+
"generate",
150+
"cloud-account",
151+
"gcp",
152+
)
153+
154+
assertTerraformSaved(t, final)
155+
156+
buildTf, _ := gcp.NewTerraform(true, false, false, true,
157+
gcp.WithProjectId(projectId),
158+
gcp.WithOrganizationIntegration(false),
159+
gcp.WithOrganizationId(organizationId),
160+
gcp.WithRegions([]string{"us-east1"}),
161+
gcp.WithProjectFilterList([]string{"p1", "p2"}),
162+
).Generate()
163+
assert.Equal(t, buildTf, tfResult)
164+
}
165+
124166
// Test configuration only generation
125167
func TestGenerationGcpConfig(t *testing.T) {
126168
os.Setenv("LW_NOCACHE", "true")

integration/test_resources/help/generate_cloud-account_gcp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Flags:
3737
-h, --help help for gcp
3838
--include_root_projects Disables logic that includes root-level projects if excluding folders (default true)
3939
--k8s_filter filter out GKE logs from GCP Audit Log sinks (default true)
40-
--organization_id string specify the organization id (only set if organization_integration is set)
40+
--organization_id string specify the organization id (only set if agentless integration or organization_integration is set)
4141
--organization_integration enable organization integration
4242
--output string location to write generated content (default is ~/lacework/gcp)
4343
--prefix string prefix that will be used at the beginning of every generated resource

lwgenerate/gcp/gcp.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,6 @@ func (args *GenerateGcpTfConfigurationArgs) validate() error {
173173
return errors.New("an Organization ID must be provided for an Organization Integration")
174174
}
175175

176-
// Validate if an organization id has been provided that this is and organization integration
177-
if !args.OrganizationIntegration && args.GcpOrganizationId != "" {
178-
return errors.New("to provide an Organization ID, Organization Integration must be true")
179-
}
180-
181176
// Validate existing Service Account values, if set
182177
if args.ExistingServiceAccount != nil {
183178
if args.ExistingServiceAccount.Name == "" ||
@@ -631,6 +626,8 @@ func createAgentless(args *GenerateGcpTfConfigurationArgs) ([]*hclwrite.Block, e
631626
}
632627
if args.OrganizationIntegration {
633628
attributes["integration_type"] = "ORGANIZATION"
629+
}
630+
if len(args.GcpOrganizationId) > 0 {
634631
attributes["organization_id"] = args.GcpOrganizationId
635632
}
636633
}

lwgenerate/gcp/gcp_test.go

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ func TestGenerateGcpTfConfigurationArgs_Generate_AuditLog(t *testing.T) {
4444
gcp.WithProjectId(projectName)),
4545
ReqProvider(projectName, moduleImportProjectLevelPubSubAuditLogWithoutConfiguration),
4646
},
47+
{
48+
"TestGenerationProjectLevelPubSubAuditLogWithoutConfigWithOrgId",
49+
gcp.NewTerraform(
50+
false,
51+
false,
52+
true,
53+
true,
54+
gcp.WithGcpServiceAccountCredentials("/path/to/credentials"),
55+
gcp.WithProjectId(projectName), gcp.WithOrganizationId("123456789")),
56+
ReqProvider(projectName, moduleImportProjectLevelPubSubAuditLogWithoutConfiguration),
57+
},
4758
{
4859
"TestGenerationProjectLevelAuditLogWithoutCredentialsAndProject",
4960
gcp.NewTerraform(false, false, true, false),
@@ -513,6 +524,16 @@ func TestGenerateGcpTfConfigurationArgs_Generate_Configuration(t *testing.T) {
513524
),
514525
ReqProvider(projectName, moduleImportProjectLevelConfigurationExistingSA),
515526
},
527+
{
528+
"TestGenerationProjectLevelConfigurationExistingSAWithOrgId",
529+
gcp.NewTerraform(false, true, false, false,
530+
gcp.WithGcpServiceAccountCredentials("/path/to/credentials"),
531+
gcp.WithProjectId(projectName),
532+
gcp.WithOrganizationId("123456789"),
533+
gcp.WithExistingServiceAccount(gcp.NewExistingServiceAccountDetails("foo", "123456789")),
534+
),
535+
ReqProvider(projectName, moduleImportProjectLevelConfigurationExistingSA),
536+
},
516537
{
517538
"TestGenerationProjectLevelConfigurationCustomIntegrationName",
518539
gcp.NewTerraform(false, true, false, false,
@@ -720,6 +741,7 @@ func TestGenerateGcpTfConfigurationArgs_Generate_Agentless(t *testing.T) {
720741
"TestGenerationProjectLevelAgentless",
721742
gcp.NewTerraform(true, false, false, false,
722743
gcp.WithProjectId(projectName),
744+
gcp.WithOrganizationId("123456789"),
723745
gcp.WithRegions([]string{"us-east1"}),
724746
),
725747
fmt.Sprintf("%s\n%s", RequiredProviders, moduleImportProjectLevelAgentless),
@@ -769,16 +791,6 @@ func TestGenerationOrganizationLevelAuditLogNoOrgId(t *testing.T) {
769791
assert.EqualError(t, err, "invalid inputs: an Organization ID must be provided for an Organization Integration")
770792
}
771793

772-
func TestGenerationOrganizationLevelAuditLogNoOrgIntegrationFlag(t *testing.T) {
773-
hcl, err := gcp.NewTerraform(false, false, true, false,
774-
gcp.WithGcpServiceAccountCredentials("/path/to/credentials"),
775-
gcp.WithProjectId(projectName),
776-
gcp.WithOrganizationId("123456789"),
777-
).Generate()
778-
assert.Empty(t, hcl)
779-
assert.EqualError(t, err, "invalid inputs: to provide an Organization ID, Organization Integration must be true")
780-
}
781-
782794
func TestGenerationNoIntegration(t *testing.T) {
783795
hcl, err := gcp.NewTerraform(false, false, false, false,
784796
gcp.WithGcpServiceAccountCredentials("/path/to/credentials"),
@@ -1181,10 +1193,11 @@ var moduleImportProjectLevelAgentless = `provider "google" {
11811193
}
11821194
11831195
module "lacework_gcp_agentless_scanning_global" {
1184-
source = "lacework/agentless-scanning/gcp"
1185-
version = "~> 2.0"
1186-
global = true
1187-
regional = true
1196+
source = "lacework/agentless-scanning/gcp"
1197+
version = "~> 2.0"
1198+
global = true
1199+
organization_id = "123456789"
1200+
regional = true
11881201
11891202
providers = {
11901203
google = google.us-east1

0 commit comments

Comments
 (0)