Skip to content

Commit 222660b

Browse files
PengyuanZhaoMatt Cadorette
andauthored
feat: refactor UX for lacework generate cloud-account aws (#1448)
* feat: refactor UX for lacework generate cloud-account aws * chore: fix make test * test: add more integration test * chore: pr feedback * chore: fix typo * feat: Add AWS Configuration Org deployment into generate command (#1451) * feat: Add AWS Configuration Org deployment into generate command Co-authored-by: Matt Cadorette <[email protected]> --------- Co-authored-by: Matt Cadorette <[email protected]>
1 parent 6ca5341 commit 222660b

File tree

12 files changed

+1904
-1752
lines changed

12 files changed

+1904
-1752
lines changed

cli/cmd/cli_unix.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package cmd
2222

2323
import (
24+
"fmt"
2425
"os"
2526

2627
"github.com/AlecAivazis/survey/v2"
@@ -35,6 +36,13 @@ var promptIconsFunc = func(icons *survey.IconSet) {
3536
icons.Question.Text = "▸"
3637
}
3738

39+
// customPromptIconsFunc configures the prompt icons with custom string for Unix systems
40+
var customPromptIconsFunc = func(s string) func(icons *survey.IconSet) {
41+
return func(icons *survey.IconSet) {
42+
icons.Question.Text = fmt.Sprintf("▸ %s", s)
43+
}
44+
}
45+
3846
// A variety of colorized icons used throughout the code
3947
var (
4048
successIcon = color.HiGreenString("✓")

cli/cmd/cli_windows.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package cmd
2020

2121
import (
22+
"fmt"
2223
"os"
2324

2425
"github.com/AlecAivazis/survey/v2"
@@ -33,6 +34,13 @@ var promptIconsFunc = func(icons *survey.IconSet) {
3334
icons.Question.Text = ">"
3435
}
3536

37+
// customPromptIconsFunc configures the prompt icons with custom string for Windows systems
38+
var customPromptIconsFunc = func(s string) func(icons *survey.IconSet) {
39+
return func(icons *survey.IconSet) {
40+
icons.Question.Text = fmt.Sprintf("> %s", s)
41+
}
42+
}
43+
3644
// A variety of colorized icons used throughout the code
3745
var (
3846
successIcon = color.HiGreenString("√")

cli/cmd/generate.go

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type SurveyQuestionWithValidationArgs struct {
5959
Response interface{}
6060
Opts []survey.AskOpt
6161
Required bool
62+
Icon string
6263
}
6364

6465
// SurveyQuestionInteractiveOnly Prompt use for question, only if the CLI is in interactive mode
@@ -82,7 +83,11 @@ func SurveyQuestionInteractiveOnly(question SurveyQuestionWithValidationArgs) er
8283
}
8384

8485
// Add custom icon
85-
question.Opts = append(question.Opts, survey.WithIcons(promptIconsFunc))
86+
if question.Icon != "" {
87+
question.Opts = append(question.Opts, survey.WithIcons(customPromptIconsFunc(question.Icon)))
88+
} else {
89+
question.Opts = append(question.Opts, survey.WithIcons(promptIconsFunc))
90+
}
8691

8792
// If noninteractive is not set, ask the question
8893
if !cli.nonInteractive {
@@ -217,20 +222,6 @@ func validateOutputLocation(dirname string) error {
217222
return nil
218223
}
219224

220-
func validateAwsSubAccounts(subaccounts []string) error {
221-
// validate the format of supplied values is correct
222-
for _, account := range subaccounts {
223-
if ok, err := regexp.MatchString(ValidateSubAccountFlagRegex, account); !ok {
224-
if err != nil {
225-
return errors.Wrap(err, "failed to validate supplied subaccount format")
226-
}
227-
return errors.New("supplied aws subaccount in invalid format")
228-
}
229-
}
230-
231-
return nil
232-
}
233-
234225
// validateStringWithRegex create survey.Validator for string with regex
235226
func validateStringWithRegex(val interface{}, regex string, errorString string) error {
236227
switch value := val.(type) {

cli/cmd/generate_aws.go

Lines changed: 716 additions & 609 deletions
Large diffs are not rendered by default.

cli/cmd/generate_aws_test.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func TestGenerateMostBasicArgs(t *testing.T) {
2424
data.Cloudtrail = true
2525
data.Config = true
2626
data.AwsRegion = "us-east-2"
27-
err := promptAwsGenerate(&data, &aws.ExistingIamRoleDetails{}, &AwsGenerateCommandExtraState{Output: "/tmp"})
27+
err := promptAwsGenerate(&data, &aws.AwsGenerateCommandExtraState{Output: "/tmp"})
2828

2929
assert.Nil(t, err)
3030
}
@@ -34,9 +34,11 @@ func TestMissingValidEntityToConfigure(t *testing.T) {
3434
defer toggleNonInteractive()
3535

3636
data := aws.GenerateAwsTfConfigurationArgs{}
37-
err := promptAwsGenerate(&data, &aws.ExistingIamRoleDetails{}, &AwsGenerateCommandExtraState{Output: "/tmp"})
37+
err := promptAwsGenerate(&data, &aws.AwsGenerateCommandExtraState{Output: "/tmp"})
38+
assert.Nil(t, err)
39+
err = data.Validate()
3840
assert.Error(t, err)
39-
assert.Equal(t, "must enable agentless, cloudtrail or config", err.Error())
41+
assert.Equal(t, "Agentless, CloudTrail or Config integration must be enabled", err.Error())
4042
}
4143

4244
func TestArnRegex(t *testing.T) {
@@ -96,9 +98,9 @@ func TestGenerationCache(t *testing.T) {
9698
defer os.RemoveAll(dir)
9799
cli.InitCache(dir)
98100

99-
extraState := &AwsGenerateCommandExtraState{}
100-
extraState.writeCache()
101-
assert.NoFileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAssetAwsExtraState)))
101+
extraState := &aws.AwsGenerateCommandExtraState{}
102+
writeExtraStateCache(extraState)
103+
assert.NoFileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAwsExtraStateKey)))
102104
})
103105
t.Run("extra state should be written if not empty", func(t *testing.T) {
104106
dir, err := os.MkdirTemp("", "lacework-cli-cache")
@@ -108,9 +110,9 @@ func TestGenerationCache(t *testing.T) {
108110
defer os.RemoveAll(dir)
109111
cli.InitCache(dir)
110112

111-
extraState := AwsGenerateCommandExtraState{Output: "/tmp"}
112-
extraState.writeCache()
113-
assert.FileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAssetAwsExtraState)))
113+
extraState := &aws.AwsGenerateCommandExtraState{Output: "/tmp"}
114+
writeExtraStateCache(extraState)
115+
assert.FileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAwsExtraStateKey)))
114116
})
115117
t.Run("iac params should not be cached when empty", func(t *testing.T) {
116118
dir, err := os.MkdirTemp("", "lacework-cli-cache")
@@ -121,8 +123,8 @@ func TestGenerationCache(t *testing.T) {
121123
cli.InitCache(dir)
122124

123125
args := aws.GenerateAwsTfConfigurationArgs{}
124-
writeAwsGenerationArgsCache(&args)
125-
assert.NoFileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAwsAssetIacParams)))
126+
writeArgsCache(&args)
127+
assert.NoFileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAwsArgsKey)))
126128
})
127129
t.Run("iac params should be cached when not empty", func(t *testing.T) {
128130
dir, err := os.MkdirTemp("", "lacework-cli-cache")
@@ -132,8 +134,8 @@ func TestGenerationCache(t *testing.T) {
132134
defer os.RemoveAll(dir)
133135
cli.InitCache(dir)
134136

135-
args := aws.GenerateAwsTfConfigurationArgs{AwsRegion: "us-east-2"}
136-
writeAwsGenerationArgsCache(&args)
137-
assert.FileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAwsAssetIacParams)))
137+
args := aws.GenerateAwsTfConfigurationArgs{AwsRegion: "us-east-2", Agentless: true}
138+
writeArgsCache(&args)
139+
assert.FileExists(t, filepath.FromSlash(fmt.Sprintf("%s/cache/standalone/%s", dir, CachedAwsArgsKey)))
138140
})
139141
}

cli/docs/lacework_generate_cloud-account_aws.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ lacework generate cloud-account aws [flags]
3939
```
4040
--agentless enable agentless integration
4141
--agentless_management_account_id string AWS management account ID for Agentless integration
42-
--agentless_monitored_account_ids strings AWS monitored account IDs for Agentless integrations
42+
--agentless_monitored_account_ids strings AWS monitored account IDs for Agentless integrations; may contain account IDs, OUs, or the organization root (e.g. 123456789000,ou-abcd-12345678,r-abcd)
43+
--agentless_monitored_accounts strings AWS monitored accounts for Agentless integrations; value format must be <aws profile>:<region>
44+
--agentless_scanning_accounts strings AWS scanning accounts for Agentless integrations; value format must be <aws profile>:<region>
4345
--apply run terraform apply without executing plan or prompting
4446
--aws_assume_role string specify aws assume role
4547
--aws_organization enable organization integration
@@ -53,7 +55,13 @@ lacework generate cloud-account aws [flags]
5355
--cloudtrail_name string specify name of cloudtrail integration
5456
--cloudtrail_org_account_mapping string Org account mapping json string. Example: '{"default_lacework_account":"main", "mapping": [{ "aws_accounts": ["123456789011"], "lacework_account": "sub-account-1"}]}'
5557
--config enable config integration
56-
--config_name string specify name of config integration
58+
--config_cf_resource_prefix string specify Cloudformation resource prefix for Config organization integration
59+
--config_lacework_access_key_id string specify AWS access key ID for Config organization integration
60+
--config_lacework_account string specify lacework account for Config organization integration
61+
--config_lacework_secret_key string specify AWS secret key for Config organization integration
62+
--config_lacework_sub_account string specify lacework sub-account for Config organization integration
63+
--config_organization_id string specify AWS organization ID for Config organization integration
64+
--config_organization_units strings specify AWS organization units for Config organization integration
5765
--consolidated_cloudtrail use consolidated trail
5866
--existing_bucket_arn string specify existing cloudtrail S3 bucket ARN
5967
--existing_iam_role_arn string specify existing iam role arn to use

0 commit comments

Comments
 (0)