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

feat(body): added additional attribute '--body' to dsv secret create & dsv home c… #134

Merged
merged 14 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion commands/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ Usage:
• %[2]s %[1]s %[4]s %[5]s
• %[2]s %[1]s --path %[4]s --data %[5]s
• %[2]s %[1]s --path %[4]s --data %[6]s
`, cst.Create, cst.NounHome, cst.ProductName, cst.ExamplePath, cst.ExampleDataJSON, cst.ExampleDataPath),
• %[2]s %[1]s --path %[4]s --body %[7]s
`, cst.Create, cst.NounHome, cst.ProductName, cst.ExamplePath, cst.ExampleDataJSON, cst.ExampleDataPath, cst.ExampleBodyDataJSON),
FlagsPredictor: []*predictor.Params{
{Name: cst.Data, Shorthand: "d", Usage: fmt.Sprintf("%s to be stored in a %s. Prefix with '@' to denote filepath (required)", strings.Title(cst.Data), cst.NounSecret), Predictor: predictor.NewPrefixFilePredictor("*")},
{Name: cst.Path, Shorthand: "r", Usage: fmt.Sprintf("Target %s to a %s (required)", cst.Path, cst.NounSecret), Predictor: predictor.NewSecretPathPredictorDefault()},
{Name: cst.DataDescription, Usage: fmt.Sprintf("Description of a %s", cst.NounSecret)},
{Name: cst.DataAttributes, Usage: fmt.Sprintf("Attributes of a %s", cst.NounSecret)},
{Name: cst.Body, Usage: fmt.Sprintf("%s, attributes and/or description of a %s. (See 'usage' above). Data will take precedence over body.", strings.Title(cst.Data), cst.NounSecret)},
},
MinNumberArgs: 2,
RunFunc: handleHomeCreate,
Expand Down
27 changes: 22 additions & 5 deletions commands/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,14 @@
• secret %[1]s %[4]s --data %[5]s
• secret %[1]s --path %[4]s --data %[5]s
• secret %[1]s --path %[4]s --data %[6]s
`, cst.Create, cst.NounSecret, cst.ProductName, cst.ExamplePath, cst.ExampleDataJSON, cst.ExampleDataPath),
• secret %[1]s --path %[4]s --body %[7]s
`, cst.Create, cst.NounSecret, cst.ProductName, cst.ExamplePath, cst.ExampleDataJSON, cst.ExampleDataPath, cst.ExampleBodyDataJSON),
FlagsPredictor: []*predictor.Params{
{Name: cst.Data, Shorthand: "d", Usage: fmt.Sprintf("%s to be stored in a %s. Prefix with '@' to denote filepath (required)", strings.Title(cst.Data), cst.NounSecret), Predictor: predictor.NewPrefixFilePredictor("*")},
{Name: cst.Path, Shorthand: "r", Usage: fmt.Sprintf("Target %s to a %s (required)", cst.Path, cst.NounSecret), Predictor: predictor.NewSecretPathPredictorDefault()},
{Name: cst.DataDescription, Usage: fmt.Sprintf("Description of a %s", cst.NounSecret)},
{Name: cst.DataAttributes, Usage: fmt.Sprintf("Attributes of a %s", cst.NounSecret)},
{Name: cst.Body, Usage: fmt.Sprintf("%s, attributes and/or description of a %s. (See 'usage' above). Data will take precedence over body.", strings.Title(cst.Data), cst.NounSecret)},
},
RunFunc: func(vcli vaultcli.CLI, args []string) int {
return handleSecretUpsertCmd(vcli, cst.NounSecret, cst.Create, args)
Expand Down Expand Up @@ -485,6 +487,7 @@
data := viper.GetString(cst.Data)
desc := viper.GetString(cst.DataDescription)
attributes := viper.GetStringMap(cst.DataAttributes)
body := viper.GetString(cst.Body)

if path == "" {
path = id
Expand All @@ -510,20 +513,34 @@
return utils.GetExecStatus(err)
}

if data == "" && desc == "" && len(attributes) == 0 {
vcli.Out().FailF("Please provide a properly formed value for at least --%s, or --%s, or --%s.",
cst.Data, cst.DataDescription, cst.DataAttributes)
if data == "" && desc == "" && len(attributes) == 0 && body == "" {
vcli.Out().FailF("Please provide a properly formed value for at least --%s, or --%s, or --%s, or --%s.",
cst.Data, cst.DataDescription, cst.DataAttributes, cst.Body)

Check warning on line 518 in commands/secret.go

View check run for this annotation

Codecov / codecov/patch

commands/secret.go#L517-L518

Added lines #L517 - L518 were not covered by tests
return 1
}

dataMap := make(map[string]interface{})
if data != "" {
bodyMap := make(map[string]interface{})
/*Only process --body attribute if all 3 of the other attributes are empty*/
if body != "" && data == "" && desc == "" && len(attributes) == 0 {
parseErr := json.Unmarshal([]byte(body), &bodyMap)
if parseErr != nil {
vcli.Out().FailF("Failed to parse passed in secret body: %v", parseErr)
return 1
}
dataMap, _ = bodyMap["data"].(map[string]interface{})
pacificcode marked this conversation as resolved.
Show resolved Hide resolved
desc, _ = bodyMap["desc"].(string)
attributes, _ = bodyMap["attributes"].(map[string]any)

Check warning on line 533 in commands/secret.go

View check run for this annotation

Codecov / codecov/patch

commands/secret.go#L526-L533

Added lines #L526 - L533 were not covered by tests
}

if data != "" && len(dataMap) == 0 {
parseErr := json.Unmarshal([]byte(data), &dataMap)
if parseErr != nil {
vcli.Out().FailF("Failed to parse passed in secret data: %v", parseErr)
return 1
}
}

postData := secretUpsertBody{
Data: dataMap,
Description: desc,
Expand Down
32 changes: 32 additions & 0 deletions commands/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,22 @@ func TestHandleSecretUpsertCmd(t *testing.T) {
method: "create",
expectedErr: nil,
},
{
name: "Happy path --body POST",
fDesc: "new description",
args: []string{"mySecret", "--body", "{\"data\":{\"key\":\"value\"}}"},
out: []byte(`test`),
method: "create",
expectedErr: nil,
},
{
name: "Happy path --data & --body POST",
fDesc: "new description",
args: []string{"mySecret", "--data", "{\"key\":\"value\"}", "--body", "{\"data\":{\"key1\":\"value1\"}}"},
out: []byte(`test`),
method: "create",
expectedErr: nil,
},
{
name: "Happy path PUT (ID)",
fDesc: "new description",
Expand All @@ -634,6 +650,22 @@ func TestHandleSecretUpsertCmd(t *testing.T) {
method: "update",
expectedErr: nil,
},
{
name: "Incorrect attributes in --body POST",
fDesc: "new description",
args: []string{"mySecret", "--body", "{\"datas\":{\"Key\":\"Values\"},\"attribute\":{\"Key2\":\"Value2\"},\"descs\":\"Secret description\"}"},
pacificcode marked this conversation as resolved.
Show resolved Hide resolved
out: []byte(`test`),
method: "create",
expectedErr: errors.NewS("message: need at least one: either data, description, or attributes"),
},
{
name: "No data in --data option && Incorrect attributes in --body POST",
fDesc: "new description",
args: []string{"mySecret", "--data", "{}", "--body", "{\"datas\":{\"key\":\"value\"}}"},
out: []byte(`test`),
method: "create",
expectedErr: errors.NewS("message: need at least one: either data, description, or attributes"),
},
{
name: "no path",
args: []string{"--description", "new description"},
Expand Down
1 change: 1 addition & 0 deletions constants/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const (
Value = "value"
Profile = "profile"
Path = "path"
Body = "body"
ID = "id"
Data = "data"
Username = "auth.username"
Expand Down
1 change: 1 addition & 0 deletions constants/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
ExampleRoleName = "gcp-svc-1"
ExampleDataJSON = `'{"Key":"Value","Key2":"Value2"}'`
ExampleDataPath = "@/tmp/data.json"
ExampleBodyDataJSON = `'{"data":{"Key":"Value"},"attributes":{"Key2":"Value2"},"desc":"Secret description"}'`
ExampleConfigPath = "@/tmp/config.yml"
ExampleUser = "kadmin"
ExampleSIEM = "LogsInc"
Expand Down
2 changes: 1 addition & 1 deletion format/writers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
}

func (w fileWriter) Write(p []byte) (n int, err error) {
err = os.WriteFile(w.filePath, p, 0664)
err = os.WriteFile(w.filePath, p, 0o664)

Check failure on line 35 in format/writers.go

View workflow job for this annotation

GitHub Actions / Trunk Check

golangci-lint(gosec)

[new] G306: Expect WriteFile permissions to be 0600 or less

Check warning on line 35 in format/writers.go

View check run for this annotation

Codecov / codecov/patch

format/writers.go#L35

Added line #L35 was not covered by tests
if err == nil {
n = len(p)
}
Expand Down
36 changes: 9 additions & 27 deletions tests/e2e/cmd_init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ func TestInitWithNoConfig(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

defer func() { deleteFile(t, config) }()

Expand Down Expand Up @@ -76,9 +74,7 @@ func TestInitWithExistingConfig(t *testing.T) {
profileName = "automation"
cacheAge = "5"
)
var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

createFile(t, config)
defer func() { deleteFile(t, config) }()
Expand Down Expand Up @@ -155,9 +151,7 @@ func TestInitOverwriteExistingConfig(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

createFile(t, config)
defer func() { deleteFile(t, config) }()
Expand Down Expand Up @@ -218,9 +212,7 @@ func TestInitAuthFails(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

createFile(t, config)
defer func() { deleteFile(t, config) }()
Expand Down Expand Up @@ -271,9 +263,7 @@ func TestInitAWSInvalid(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

createFile(t, config)
defer func() { deleteFile(t, config) }()
Expand Down Expand Up @@ -323,9 +313,7 @@ func TestInitClientCredsInvalid(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

createFile(t, config)
defer func() { deleteFile(t, config) }()
Expand Down Expand Up @@ -376,9 +364,7 @@ func TestInitProfileExists(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

defer func() { deleteFile(t, config) }()

Expand Down Expand Up @@ -427,9 +413,7 @@ func TestInitWrongStoreType(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

cmd := []string{
"init", fmt.Sprintf("--dev=%s", e.domain), fmt.Sprintf("--config=%s", config),
Expand All @@ -456,9 +440,7 @@ func TestInitWithNoStore(t *testing.T) {
}
e := newEnv()

var (
config = filepath.Join(e.tmpDirPath, "e2e-configuration.yml")
)
config := filepath.Join(e.tmpDirPath, "e2e-configuration.yml")

defer func() { deleteFile(t, config) }()

Expand Down
6 changes: 4 additions & 2 deletions utils/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
}
type envProvider struct{}

var GetEnvProviderFunc func() EnvProvider
var e EnvProvider
var (
GetEnvProviderFunc func() EnvProvider

Check failure on line 16 in utils/env.go

View workflow job for this annotation

GitHub Actions / Trunk Check

golangci-lint(gochecknoglobals)

[new] GetEnvProviderFunc is a global variable
e EnvProvider

Check failure on line 17 in utils/env.go

View workflow job for this annotation

GitHub Actions / Trunk Check

golangci-lint(gochecknoglobals)

[new] e is a global variable
)

func NewEnvProvider() EnvProvider {
return &envProvider{}
Expand Down
2 changes: 1 addition & 1 deletion utils/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func ParseHours(s string) (int, error) {
return 0, nil
}

var invalidFormatErr = errors.New("invalid time format - submit an integer followed by one of the following: h, H, d, D, w, W")
invalidFormatErr := errors.New("invalid time format - submit an integer followed by one of the following: h, H, d, D, w, W")
units := []string{"h", "H", "d", "D", "w", "W"}
n, unit := s[:len(s)-1], string(s[len(s)-1])

Expand Down
Loading