open-vault/command/patch_test.go
Alexander Scheel 1721cc9f75
Add PATCH support to Vault CLI (#17650)
* Add patch support to CLI

This is based off the existing write command, using the
JSONMergePatch(...) API client method rather than Write(...), allowing
us to update specific fields.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add documentation on PATCH support

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add changelog

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-10-26 14:30:40 -04:00

203 lines
4.3 KiB
Go

package command
import (
"io"
"strings"
"testing"
"github.com/hashicorp/vault/api"
"github.com/mitchellh/cli"
)
func testPatchCommand(tb testing.TB) (*cli.MockUi, *PatchCommand) {
tb.Helper()
ui := cli.NewMockUi()
return ui, &PatchCommand{
BaseCommand: &BaseCommand{
UI: ui,
},
}
}
func TestPatchCommand_Run(t *testing.T) {
t.Parallel()
cases := []struct {
name string
args []string
out string
code int
}{
{
"not_enough_args",
[]string{},
"Not enough arguments",
1,
},
{
"empty_kvs",
[]string{"secret/write/foo"},
"Must supply data or use -force",
1,
},
{
"force_kvs",
[]string{"-force", "pki/roles/example"},
"Success!",
0,
},
{
"force_f_kvs",
[]string{"-f", "pki/roles/example"},
"Success!",
0,
},
{
"kvs_no_value",
[]string{"pki/roles/example", "foo"},
"Failed to parse K=V data",
1,
},
{
"single_value",
[]string{"pki/roles/example", "allow_localhost=true"},
"Success!",
0,
},
{
"multi_value",
[]string{"pki/roles/example", "allow_localhost=true", "allowed_domains=true"},
"Success!",
0,
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
client, closer := testVaultServer(t)
defer closer()
if err := client.Sys().Mount("pki", &api.MountInput{
Type: "pki",
}); err != nil {
t.Fatalf("pki mount error: %#v", err)
}
if _, err := client.Logical().Write("pki/roles/example", nil); err != nil {
t.Fatalf("failed to prime role: %v", err)
}
if _, err := client.Logical().Write("pki/root/generate/internal", map[string]interface{}{
"key_type": "ec",
"common_name": "Root X1",
}); err != nil {
t.Fatalf("failed to prime CA: %v", err)
}
ui, cmd := testPatchCommand(t)
cmd.client = client
code := cmd.Run(tc.args)
if code != tc.code {
t.Errorf("expected %d to be %d", code, tc.code)
}
combined := ui.OutputWriter.String() + ui.ErrorWriter.String()
if !strings.Contains(combined, tc.out) {
t.Errorf("expected %q to contain %q", combined, tc.out)
}
})
}
t.Run("stdin_full", func(t *testing.T) {
t.Parallel()
client, closer := testVaultServer(t)
defer closer()
if err := client.Sys().Mount("pki", &api.MountInput{
Type: "pki",
}); err != nil {
t.Fatalf("pki mount error: %#v", err)
}
if _, err := client.Logical().Write("pki/roles/example", nil); err != nil {
t.Fatalf("failed to prime role: %v", err)
}
if _, err := client.Logical().Write("pki/root/generate/internal", map[string]interface{}{
"key_type": "ec",
"common_name": "Root X1",
}); err != nil {
t.Fatalf("failed to prime CA: %v", err)
}
stdinR, stdinW := io.Pipe()
go func() {
stdinW.Write([]byte(`{"allow_localhost":"false","allow_wildcard_certificates":"false"}`))
stdinW.Close()
}()
ui, cmd := testPatchCommand(t)
cmd.client = client
cmd.testStdin = stdinR
code := cmd.Run([]string{
"pki/roles/example", "-",
})
if code != 0 {
combined := ui.OutputWriter.String() + ui.ErrorWriter.String()
t.Fatalf("expected retcode=%d to be 0\nOutput:\n%v", code, combined)
}
secret, err := client.Logical().Read("pki/roles/example")
if err != nil {
t.Fatal(err)
}
if secret == nil || secret.Data == nil {
t.Fatal("expected secret to have data")
}
if exp, act := false, secret.Data["allow_localhost"].(bool); exp != act {
t.Errorf("expected allowed_localhost=%v to be %v", act, exp)
}
if exp, act := false, secret.Data["allow_wildcard_certificates"].(bool); exp != act {
t.Errorf("expected allow_wildcard_certificates=%v to be %v", act, exp)
}
})
t.Run("communication_failure", func(t *testing.T) {
t.Parallel()
client, closer := testVaultServerBad(t)
defer closer()
ui, cmd := testPatchCommand(t)
cmd.client = client
code := cmd.Run([]string{
"foo/bar", "a=b",
})
if exp := 2; code != exp {
t.Errorf("expected %d to be %d", code, exp)
}
expected := "Error writing data to foo/bar: "
combined := ui.OutputWriter.String() + ui.ErrorWriter.String()
if !strings.Contains(combined, expected) {
t.Errorf("expected %q to contain %q", combined, expected)
}
})
t.Run("no_tabs", func(t *testing.T) {
t.Parallel()
_, cmd := testPatchCommand(t)
assertNoTabs(t, cmd)
})
}