Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(GROW-2950): disable use of gcp storage audit from generate #1643

Merged
merged 11 commits into from
Jul 16, 2024
191 changes: 11 additions & 180 deletions cli/cmd/generate_gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ var (
QuestionGcpEnableAgentless = "Enable Agentless integration?"
QuestionGcpEnableConfiguration = "Enable Configuration integration?"
QuestionGcpEnableAuditLog = "Enable Audit Log integration?"
QuestionUsePubSubAudit = "Use Pub Sub Audit Log?"
QuestionGcpOrganizationIntegration = "Organization integration?"
QuestionGcpOrganizationID = "Specify the GCP organization ID:"
QuestionGcpProjectID = "Specify the project ID to be used to provision Lacework resources:"
Expand All @@ -35,16 +34,9 @@ var (
"you want to monitor: (optional)"
QuestionGcpRegions = "Specify a comma separated list of regions to deploy Agentless:"

GcpAdvancedOptAuditLog = "Configure additional Audit Log options"
QuestionGcpUseExistingBucket = "Use an existing bucket?"
QuestionGcpExistingBucketName = "Specify an existing bucket name:"
QuestionGcpConfigureNewBucket = "Configure settings for new bucket?"
QuestionGcpBucketRegion = "Specify the bucket region: (optional)"
QuestionGcpCustomBucketName = "Specify a custom bucket name: (optional)"
QuestionGcpBucketLifecycle = "Specify the bucket lifecycle rule age: (optional)"
QuestionGcpEnableUBLA = "Enable uniform bucket level access(UBLA)?"
QuestionGcpUseExistingSink = "Use an existing sink?"
QuestionGcpExistingSinkName = "Specify the existing sink name"
GcpAdvancedOptAuditLog = "Configure additional Audit Log options"
QuestionGcpUseExistingSink = "Use an existing sink?"
QuestionGcpExistingSinkName = "Specify the existing sink name"

GcpAdvancedOptIntegrationName = "Customize integration name(s)"
QuestionGcpConfigurationIntegrationName = "Specify a custom configuration integration name: (optional)"
Expand Down Expand Up @@ -111,27 +103,22 @@ See help output for more details on the parameter value(s) required for Terrafor
gcp.WithExistingServiceAccount(GenerateGcpCommandState.ExistingServiceAccount),
gcp.WithConfigurationIntegrationName(GenerateGcpCommandState.ConfigurationIntegrationName),
gcp.WithAuditLogLabels(GenerateGcpCommandState.AuditLogLabels),
gcp.WithBucketLabels(GenerateGcpCommandState.BucketLabels),
gcp.WithPubSubSubscriptionLabels(GenerateGcpCommandState.PubSubSubscriptionLabels),
gcp.WithPubSubTopicLabels(GenerateGcpCommandState.PubSubTopicLabels),
gcp.WithCustomBucketName(GenerateGcpCommandState.CustomBucketName),
gcp.WithBucketRegion(GenerateGcpCommandState.BucketRegion),
gcp.WithExistingLogBucketName(GenerateGcpCommandState.ExistingLogBucketName),
gcp.WithExistingLogSinkName(GenerateGcpCommandState.ExistingLogSinkName),
gcp.WithAuditLogIntegrationName(GenerateGcpCommandState.AuditLogIntegrationName),
gcp.WithLaceworkProfile(GenerateGcpCommandState.LaceworkProfile),
gcp.WithLogBucketLifecycleRuleAge(GenerateGcpCommandState.LogBucketLifecycleRuleAge),
gcp.WithFoldersToInclude(GenerateGcpCommandState.FoldersToInclude),
gcp.WithFoldersToExclude(GenerateGcpCommandState.FoldersToExclude),
gcp.WithCustomFilter(GenerateGcpCommandState.CustomFilter),
gcp.WithGoogleWorkspaceFilter(GenerateGcpCommandState.GoogleWorkspaceFilter),
gcp.WithK8sFilter(GenerateGcpCommandState.K8sFilter),
gcp.WithPrefix(GenerateGcpCommandState.Prefix),
gcp.WithWaitTime(GenerateGcpCommandState.WaitTime),
gcp.WithEnableUBLA(GenerateGcpCommandState.EnableUBLA),
gcp.WithMultipleProject(GenerateGcpCommandState.Projects),
gcp.WithProjectFilterList(GenerateGcpCommandState.ProjectFilterList),
gcp.WithRegions(GenerateGcpCommandState.Regions),
gcp.WithUsePubSubAudit(true), // always set to true, storage based integration deprecated
}

if GenerateGcpCommandState.OrganizationIntegration {
Expand Down Expand Up @@ -212,15 +199,6 @@ See help output for more details on the parameter value(s) required for Terrafor
}
}

// Validate gcp region, if passed
region, err := cmd.Flags().GetString("bucket_region")
if err != nil {
return errors.Wrap(err, "failed to load command flags")
}
if err := validateGcpRegion(region); err != nil {
return err
}

projectId, err := cmd.Flags().GetString("project_id")
if err != nil {
return errors.Wrap(err, "failed to load command flags")
Expand Down Expand Up @@ -283,20 +261,17 @@ See help output for more details on the parameter value(s) required for Terrafor
)

type GcpGenerateCommandExtraState struct {
AskAdvanced bool
Output string
ConfigureNewBucketSettings bool
UseExistingServiceAccount bool
UseExistingBucket bool
UseExistingSink bool
TerraformApply bool
AskAdvanced bool
Output string
UseExistingServiceAccount bool
UseExistingSink bool
TerraformApply bool
}

func (gcp *GcpGenerateCommandExtraState) isEmpty() bool {
return gcp.Output == "" &&
!gcp.AskAdvanced &&
!gcp.UseExistingServiceAccount &&
!gcp.UseExistingBucket &&
!gcp.UseExistingSink &&
!gcp.TerraformApply
}
Expand Down Expand Up @@ -361,22 +336,6 @@ func initGenerateGcpTfCommandFlags() {
"configuration_integration_name",
"",
"specify a custom configuration integration name")
generateGcpTfCommand.PersistentFlags().StringVar(
&GenerateGcpCommandState.CustomBucketName,
"custom_bucket_name",
"",
"override prefix based storage bucket name generation with a custom name")
// TODO: Implement AuditLogLabels, BucketLabels, PubSubSubscriptionLabels & PubSubTopicLabels
generateGcpTfCommand.PersistentFlags().StringVar(
&GenerateGcpCommandState.BucketRegion,
"bucket_region",
"",
"specify bucket region")
generateGcpTfCommand.PersistentFlags().StringVar(
&GenerateGcpCommandState.ExistingLogBucketName,
"existing_bucket_name",
"",
"specify existing bucket name")
generateGcpTfCommand.PersistentFlags().StringVar(
&GenerateGcpCommandState.ExistingLogSinkName,
"existing_sink_name",
Expand All @@ -393,27 +352,8 @@ func initGenerateGcpTfCommandFlags() {
[]string{},
"List of GCP regions to deploy for Agentless integration")

// DEPRECATED
generateGcpTfCommand.PersistentFlags().BoolVar(
&GenerateGcpCommandState.EnableForceDestroyBucket,
"enable_force_destroy_bucket",
true,
"enable force bucket destroy")
errcheckWARN(generateGcpTfCommand.PersistentFlags().MarkDeprecated(
"enable_force_destroy_bucket", "by default, force destroy is enabled.",
))
// ---

generateGcpTfCommand.PersistentFlags().BoolVar(
&GenerateGcpCommandState.EnableUBLA,
"enable_ubla",
true,
"enable universal bucket level access(ubla)")
generateGcpTfCommand.PersistentFlags().IntVar(
&GenerateGcpCommandState.LogBucketLifecycleRuleAge,
"bucket_lifecycle_rule_age",
-1,
"specify the lifecycle rule age")
generateGcpTfCommand.PersistentFlags().StringVar(
&GenerateGcpCommandState.CustomFilter,
"custom_filter",
Expand Down Expand Up @@ -476,39 +416,15 @@ func initGenerateGcpTfCommandFlags() {
generateGcpTfCommand.PersistentFlags().BoolVar(
&GenerateGcpCommandState.UsePubSubAudit,
"use_pub_sub",
false,
"use pub/sub for the audit log data rather than bucket")
true,
"deprecated: pub/sub audit log integration is always used and only supported type")
generateGcpTfCommand.PersistentFlags().StringSliceVar(
&GenerateGcpCommandState.Projects,
"projects",
[]string{},
"list of project IDs to integrate with (project-level integrations)")
}

// survey.Validator for gcp region
func validateGcpRegion(val interface{}) error {
switch value := val.(type) {
case string:
// as this field is optional, it is valid for this field to be empty
if value != "" {
// if value doesn't match regex, return invalid arn
ok, err := regexp.MatchString(GcpRegionRegex, value)
if err != nil {
return errors.Wrap(err, "failed to validate input")
}

if !ok {
return errors.New("invalid region name supplied")
}
}
default:
// if the value passed is not a string
return errors.New("value must be a string")
}

return nil
}

func promptGcpAgentlessQuestions(
config *gcp.GenerateGcpTfConfigurationArgs,
extraState *GcpGenerateCommandExtraState,
Expand All @@ -534,20 +450,6 @@ func promptGcpAuditLogQuestions(
extraState *GcpGenerateCommandExtraState,
) error {

// Only ask these questions if configure audit log is true
if err := SurveyMultipleQuestionWithValidation([]SurveyQuestionWithValidationArgs{
{
Prompt: &survey.Confirm{Message: QuestionUsePubSubAudit, Default: config.UsePubSubAudit},
Checks: []*bool{&config.AuditLog},
Response: &config.UsePubSubAudit,
},
}, config.AuditLog); err != nil {
return err
}
// Present the user with Bucket Configuration options, if required
if err := promptGcpBucketConfiguration(config, extraState); err != nil {
return err
}
err := SurveyMultipleQuestionWithValidation([]SurveyQuestionWithValidationArgs{
{
Prompt: &survey.Confirm{Message: QuestionGcpUseExistingSink, Default: extraState.UseExistingSink},
Expand All @@ -571,77 +473,6 @@ func promptGcpAuditLogQuestions(
return err
}

func promptGcpBucketConfiguration(
config *gcp.GenerateGcpTfConfigurationArgs, extraState *GcpGenerateCommandExtraState,
) error {
// Prompt to configure bucket information (not required when using the Pub Sub Audit Log)
if err := SurveyMultipleQuestionWithValidation([]SurveyQuestionWithValidationArgs{
{
Prompt: &survey.Confirm{Message: QuestionGcpUseExistingBucket, Default: extraState.UseExistingBucket},
Checks: []*bool{&config.AuditLog, usePubSubActivityDisabled(config)},
Response: &extraState.UseExistingBucket,
},
{
Prompt: &survey.Input{Message: QuestionGcpExistingBucketName, Default: config.ExistingLogBucketName},
Checks: []*bool{&config.AuditLog, &extraState.UseExistingBucket, usePubSubActivityDisabled(config)},
Required: true,
Response: &config.ExistingLogBucketName,
},
}, config.AuditLog); err != nil {
return err
}

newBucket := !extraState.UseExistingBucket
err := SurveyMultipleQuestionWithValidation([]SurveyQuestionWithValidationArgs{
{
Prompt: &survey.Confirm{Message: QuestionGcpConfigureNewBucket, Default: extraState.ConfigureNewBucketSettings},
Checks: []*bool{&config.AuditLog, &newBucket, usePubSubActivityDisabled(config)},
Required: true,
Response: &extraState.ConfigureNewBucketSettings,
},
{
Prompt: &survey.Input{Message: QuestionGcpBucketRegion, Default: config.BucketRegion},
Checks: []*bool{&config.AuditLog,
&newBucket,
&extraState.ConfigureNewBucketSettings,
usePubSubActivityDisabled(config)},
Opts: []survey.AskOpt{survey.WithValidator(validateGcpRegion)},
Response: &config.BucketRegion,
},
{
Prompt: &survey.Input{Message: QuestionGcpCustomBucketName, Default: config.CustomBucketName},
Checks: []*bool{&config.AuditLog,
&newBucket,
&extraState.ConfigureNewBucketSettings,
usePubSubActivityDisabled(config)},
Response: &config.CustomBucketName,
},
{
Prompt: &survey.Input{Message: QuestionGcpBucketLifecycle, Default: "-1"},
Checks: []*bool{&config.AuditLog,
&newBucket,
&extraState.ConfigureNewBucketSettings,
usePubSubActivityDisabled(config)},
Response: &config.LogBucketLifecycleRuleAge,
},
{
Prompt: &survey.Confirm{Message: QuestionGcpEnableUBLA, Default: config.EnableUBLA},
Checks: []*bool{&config.AuditLog,
&newBucket,
&extraState.ConfigureNewBucketSettings,
usePubSubActivityDisabled(config)},
Required: true,
Response: &config.EnableUBLA,
},
}, config.AuditLog)

return err
}

func usePubSubActivityDisabled(config *gcp.GenerateGcpTfConfigurationArgs) *bool {
usePubSubActivityDisabled := !config.UsePubSubAudit
return &usePubSubActivityDisabled
}
func promptGcpExistingServiceAccountQuestions(config *gcp.GenerateGcpTfConfigurationArgs) error {
// ensure struct is initialized
if config.ExistingServiceAccount == nil {
Expand Down
Loading
Loading