Skip to content

Commit

Permalink
Fix hashicorp#613 - Add seal_wrap to resource "vault_mount"
Browse files Browse the repository at this point in the history
Adds support to configure the `seal_wrap` boolean flag
during creating time of a vault_mount as specified in
https://www.vaultproject.io/api/system/mounts.html#seal_wrap

-
hashicorp#615
  • Loading branch information
weitzjdevk authored and adongy committed Dec 18, 2019
1 parent 3e3a31b commit 498f6aa
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 2 deletions.
15 changes: 13 additions & 2 deletions vault/resource_mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ func mountResource() *schema.Resource {
ForceNew: false,
Description: "Specifies mount type specific options that are passed to the backend",
},

"seal_wrap": {
Type: schema.TypeBool,
Required: false,
Optional: true,
ForceNew: true,
Computed: true,
Description: "Enable seal wrapping for the mount, causing values stored by the mount to be wrapped by the seal's encryption capability",
},
},
}
}
Expand All @@ -97,8 +106,9 @@ func mountWrite(d *schema.ResourceData, meta interface{}) error {
DefaultLeaseTTL: fmt.Sprintf("%ds", d.Get("default_lease_ttl_seconds")),
MaxLeaseTTL: fmt.Sprintf("%ds", d.Get("max_lease_ttl_seconds")),
},
Local: d.Get("local").(bool),
Options: opts(d),
Local: d.Get("local").(bool),
Options: opts(d),
SealWrap: d.Get("seal_wrap").(bool),
}

path := d.Get("path").(string)
Expand Down Expand Up @@ -207,6 +217,7 @@ func mountRead(d *schema.ResourceData, meta interface{}) error {
d.Set("accessor", mount.Accessor)
d.Set("local", mount.Local)
d.Set("options", mount.Options)
d.Set("seal_wrap", mount.SealWrap)

return nil
}
Expand Down
114 changes: 114 additions & 0 deletions vault/resource_mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type mountConfig struct {
path string
mountType string
version string
seal_wrap bool
}

func TestZeroTTLDoesNotCauseUpdate(t *testing.T) {
Expand Down Expand Up @@ -86,6 +87,26 @@ func TestResourceMount_Local(t *testing.T) {
})
}

// Test SealWrap flag

func TestResourceMount_SealWrap(t *testing.T) {
path := "example-" + acctest.RandString(10)
resource.Test(t, resource.TestCase{
Providers: testProviders,
PreCheck: func() { testAccPreCheck(t) },
Steps: []resource.TestStep{
{
Config: testResourceMount_InitialConfigSealWrap(path),
Check: testResourceMount_InitialCheckSealWrap(path),
},
{
Config: testResourceMount_UpdateConfigSealWrap,
Check: testResourceMount_UpdateCheckSealWrap,
},
},
})
}

func TestResourceMount_KVV2(t *testing.T) {
path := acctest.RandomWithPrefix("example")
kvv2Cfg := fmt.Sprintf(`
Expand Down Expand Up @@ -335,6 +356,99 @@ func testResourceMount_UpdateCheckLocalMount(s *terraform.State) error {
return nil
}

func testResourceMount_InitialConfigSealWrap(path string) string {
return fmt.Sprintf(`
resource "vault_mount" "test" {
path = "%s"
type = "kv"
description = "Example local mount for testing"
default_lease_ttl_seconds = 3600
max_lease_ttl_seconds = 36000
options = {
version = "1"
}
seal_wrap = true
}
`, path)
}

func testResourceMount_InitialCheckSealWrap(expectedPath string) resource.TestCheckFunc {
return func(s *terraform.State) error {
resourceState := s.Modules[0].Resources["vault_mount.test"]
if resourceState == nil {
return fmt.Errorf("resource not found in state")
}

instanceState := resourceState.Primary
if instanceState == nil {
return fmt.Errorf("resource has no primary instance")
}

path := instanceState.ID

if path != instanceState.Attributes["path"] {
return fmt.Errorf("id %q doesn't match path %q", path, instanceState.Attributes["path"])
}

if path != expectedPath {
return fmt.Errorf("unexpected path %q, expected %q", path, expectedPath)
}

mount, err := findMount(path)
if err != nil {
return fmt.Errorf("error reading back mount %q: %s", path, err)
}

if wanted := true; mount.SealWrap != wanted {
return fmt.Errorf("seal_wrap is %v; wanted %t", mount.SealWrap, wanted)
}

return nil
}
}

var testResourceMount_UpdateConfigSealWrap = `
resource "vault_mount" "test" {
path = "remountingExample"
type = "kv"
description = "Example mount for testing"
default_lease_ttl_seconds = 7200
max_lease_ttl_seconds = 72000
options = {
version = "1"
}
seal_wrap = false
}
`

func testResourceMount_UpdateCheckSealWrap(s *terraform.State) error {
resourceState := s.Modules[0].Resources["vault_mount.test"]
instanceState := resourceState.Primary

path := instanceState.ID

if path != instanceState.Attributes["path"] {
return fmt.Errorf("id doesn't match path")
}

if path != "remountingExample" {
return fmt.Errorf("unexpected path value")
}

mount, err := findMount(path)
if err != nil {
return fmt.Errorf("error reading back mount: %s", err)
}

if wanted := false; mount.SealWrap != wanted {
return fmt.Errorf("seal_wrap is %v; wanted %t", mount.SealWrap, wanted)
}

return nil
}

func findMount(path string) (*api.MountOutput, error) {
client := testProvider.Meta().(*api.Client)

Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/mount.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The following arguments are supported:

* `options` - (Optional) Specifies mount type specific options that are passed to the backend

* `seal_wrap` - (Optional) Boolean flag that can be explicitly set to true to enable seal wrapping for the mount, causing values stored by the mount to be wrapped by the seal's encryption capability

## Attributes Reference

In addition to the fields above, the following attributes are exported:
Expand Down

0 comments on commit 498f6aa

Please sign in to comment.