Skip to content

Commit

Permalink
feat(cli): --remove_tenant from config file
Browse files Browse the repository at this point in the history
A user will be able to configure a persistent tenant with the command:
```
$ lacework configure --tenant sub-account
```

To remove the configured tenant use the `--remove_tenant` flag:
```
$ lacework configure --remove_tenant
```

Signed-off-by: Salim Afiune Maya <afiune@lacework.net>
  • Loading branch information
afiune committed Jul 31, 2020
1 parent d34f565 commit c1f14b4
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 2 deletions.
26 changes: 24 additions & 2 deletions cli/cmd/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ var (
// configureJsonFile is the API key file downloaded form the Lacework WebUI
configureJsonFile string

// removeTenant tells the configure command to remove the configured tenant
// from the profile that is being configured
removeTenant bool

// configureCmd represents the configure command
configureCmd = &cobra.Command{
Use: "configure",
Expand All @@ -102,7 +106,10 @@ specify a profile to use.
You can configure multiple profiles by using the --profile argument. If a
config file does not exist (the default location is ~/.lacework.toml), the
Lacework CLI will create it for you.`,
Lacework CLI will create it for you.
For organization administrators, use the argument --tenant to configure a
sub-account. To remove this configuration pass the --remove_tenant flag.`,
RunE: func(_ *cobra.Command, _ []string) error {
return promptConfigureSetup()
},
Expand All @@ -115,6 +122,10 @@ func init() {
configureCmd.Flags().StringVarP(&configureJsonFile,
"json_file", "j", "", "loads the generated API key JSON file from the WebUI",
)

configureCmd.Flags().BoolVar(&removeTenant,
"remove_tenant", false, "removes the configured tenant of the profile being modified",
)
}

func promptConfigureSetup() error {
Expand Down Expand Up @@ -202,6 +213,17 @@ func promptConfigureSetup() error {
newCreds.ApiSecret = cli.Secret
}

tenantMsg := ""
if len(cli.Tenant) != 0 {
newCreds.Tenant = cli.Tenant
tenantMsg = fmt.Sprintf("Tenant '%s' configured. ", cli.Tenant)
}

if removeTenant && newCreds.Tenant != "" {
tenantMsg = fmt.Sprintf("Tenant '%s' removed. ", newCreds.Tenant)
newCreds.Tenant = ""
}

if err := newCreds.Verify(); err != nil {
return errors.Wrap(err, "unable to configure the command-line")
}
Expand Down Expand Up @@ -240,7 +262,7 @@ func promptConfigureSetup() error {
return err
}

cli.OutputHuman("You are all set!\n")
cli.OutputHuman("%sYou are all set!\n", tenantMsg)
return nil
}

Expand Down
108 changes: 108 additions & 0 deletions integration/configure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,114 @@ func TestConfigureCommandWithExistingConfigAndMultiProfile(t *testing.T) {
`, laceworkTOML, "there is a problem with the generated config")
}

func TestConfigureCommandWithTenant(t *testing.T) {
_, laceworkTOML := runConfigureTest(t,
func(c *expect.Console) {
c.ExpectString("Account:")
c.SendLine("test-account")
c.ExpectString("Access Key ID:")
c.SendLine("INTTEST_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890AAABBBCCC00")
c.ExpectString("Secret Access Key:")
c.SendLine("_00000000000000000000000000000000")
c.ExpectString("You are all set!")
},
"configure", "--tenant", "sub-account",
)

assert.Equal(t, `[default]
account = "test-account"
api_key = "INTTEST_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890AAABBBCCC00"
api_secret = "_00000000000000000000000000000000"
tenant = "sub-account"
`, laceworkTOML, "there is a problem with the generated config")
}

func TestConfigureCommandWithExistingConfigAndMultiProfileWithRemoveTenantFlag(t *testing.T) {
dir := createTOMLConfig()
defer os.RemoveAll(dir)

_, laceworkTOML := runConfigureTestFromDir(t, dir,
func(c *expect.Console) {
c.ExpectString("Account:")
c.SendLine("") // using the default, which should be auto-populated from the provided --profile flag
c.ExpectString("Access Key ID:")
c.SendLine("") // using the default, which should be auto-populated from the provided --profile flag
c.ExpectString("Secret Access Key:")
c.SendLine("") // using the default, which should be auto-populated from the provided --profile flag
c.ExpectString("Tenant 'sub-acc' removed. You are all set!")
},
"configure", "--profile", "integration", "--remove_tenant",
)

assert.Equal(t, `[default]
account = "test.account"
api_key = "INTTEST_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890AAABBBCCC00"
api_secret = "_00000000000000000000000000000000"
[dev]
account = "dev.example"
api_key = "DEVDEV_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890AAABBBCCC000"
api_secret = "_11111111111111111111111111111111"
[integration]
account = "integration"
api_key = "INTEGRATION_3DF1234AABBCCDD5678XXYYZZ1234ABC8BEC6500DC70001"
api_secret = "_1234abdc00ff11vv22zz33xyz1234abc"
`, laceworkTOML, "there is a problem with the generated config") // NOTE: there is no tenant
}

func TestConfigureCommandNonInteractiveWithTenantPlusRemoval(t *testing.T) {
home, err := ioutil.TempDir("", "lacework-cli")
if err != nil {
panic(err)
}

defer os.RemoveAll(home)
out, errB, exitcode := LaceworkCLIWithHome(home, "configure",
"--noninteractive",
"-a", "my-account",
"-k", "my-key",
"-s", "my-secret",
"-t", "sub-account",
)

assert.Empty(t, errB.String())
assert.Equal(t, 0, exitcode)
assert.Equal(t, "Tenant 'sub-account' configured. You are all set!\n", out.String(),
"you are not all set, check configure cmd")

configPath := path.Join(home, ".lacework.toml")
assert.FileExists(t, configPath, "the configuration file is missing")
laceworkTOML, err := ioutil.ReadFile(configPath)
if err != nil {
panic(err)
}

assert.Equal(t, `[default]
account = "my-account"
api_key = "my-key"
api_secret = "my-secret"
tenant = "sub-account"
`, string(laceworkTOML), "there is a problem with the generated config")

// removing the tenant configuration
out, errB, exitcode = LaceworkCLIWithHome(home, "configure", "--noninteractive", "--remove_tenant")
assert.Empty(t, errB.String())
assert.Equal(t, 0, exitcode)
assert.Equal(t, "Tenant 'sub-account' removed. You are all set!\n", out.String(),
"you are not all set, check configure cmd")
laceworkTOML, err = ioutil.ReadFile(configPath)
if err != nil {
panic(err)
}

assert.Equal(t, `[default]
account = "my-account"
api_key = "my-key"
api_secret = "my-secret"
`, string(laceworkTOML), "there is a problem with the generated config") // NOTE: no tenant anymore
}

func TestConfigureCommandErrors(t *testing.T) {
_, laceworkTOML := runConfigureTest(t,
func(c *expect.Console) {
Expand Down
4 changes: 4 additions & 0 deletions integration/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,16 @@ You can configure multiple profiles by using the --profile argument. If a
config file does not exist (the default location is ~/.lacework.toml), the
Lacework CLI will create it for you.
For organization administrators, use the argument --tenant to configure a
sub-account. To remove this configuration pass the --remove_tenant flag.
Usage:
lacework configure [flags]
Flags:
-h, --help help for configure
-j, --json_file string loads the generated API key JSON file from the WebUI
--remove_tenant removes the configured tenant of the profile being modified
Global Flags:
-a, --account string account subdomain of URL (i.e. <ACCOUNT>.lacework.net)
Expand Down

0 comments on commit c1f14b4

Please sign in to comment.