Skip to content

Commit

Permalink
Add reuse_wrapping_token functionality. (#1166)
Browse files Browse the repository at this point in the history
Co-authored-by: Ben Ash <32777270+benashz@users.noreply.github.com>
  • Loading branch information
melbit-michaelw and benashz committed Mar 15, 2022
1 parent 91f40a2 commit c324dc8
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 13 deletions.
26 changes: 20 additions & 6 deletions vault/resource_approle_auth_backend_role_secret_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ func approleAuthBackendRoleSecretIDResource(name string) *schema.Resource {
},
},

"with_wrapped_accessor": {
Type: schema.TypeBool,
Optional: true,
Description: "Use the wrapped secret-id accessor as the id of this resource. If false, a fresh secret-id will be regenerated whenever the wrapping token is expired or invalidated through unwrapping.",
ForceNew: true,
},

"accessor": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -147,6 +154,7 @@ func approleAuthBackendRoleSecretIDCreate(d *schema.ResourceData, meta interface
} else {
data["metadata"] = ""
}
withWrappedAccessor := d.Get("with_wrapped_accessor").(bool)

wrappingTTL, wrapped := d.GetOk("wrapping_ttl")

Expand All @@ -170,7 +178,11 @@ func approleAuthBackendRoleSecretIDCreate(d *schema.ResourceData, meta interface
var accessor string

if wrapped {
accessor = resp.WrapInfo.Accessor
if withWrappedAccessor {
accessor = resp.WrapInfo.WrappedAccessor
} else {
accessor = resp.WrapInfo.Accessor
}
d.Set("wrapping_token", resp.WrapInfo.Token)
d.Set("wrapping_accessor", accessor)
} else {
Expand All @@ -179,7 +191,7 @@ func approleAuthBackendRoleSecretIDCreate(d *schema.ResourceData, meta interface
d.Set("accessor", accessor)
}

d.SetId(approleAuthBackendRoleSecretIDID(backend, role, accessor, wrapped))
d.SetId(approleAuthBackendRoleSecretIDID(backend, role, accessor, wrapped, withWrappedAccessor))

return approleAuthBackendRoleSecretIDRead(d, meta)
}
Expand All @@ -194,8 +206,10 @@ func approleAuthBackendRoleSecretIDRead(d *schema.ResourceData, meta interface{}
}

// If the ID is wrapped, there is no information available other than whether
// the wrapping token is still valid.
if wrapped {
// the wrapping token is still valid, unless we are planning to re-use it.
withWrappedAccessor := d.Get("with_wrapped_accessor").(bool)

if wrapped && !withWrappedAccessor {
valid, err := approleAuthBackendRoleSecretIDExists(d, meta)
if err != nil {
return err
Expand Down Expand Up @@ -330,8 +344,8 @@ func approleAuthBackendRoleSecretIDExists(d *schema.ResourceData, meta interface
return resp != nil, nil
}

func approleAuthBackendRoleSecretIDID(backend, role, accessor string, wrapped bool) string {
if wrapped {
func approleAuthBackendRoleSecretIDID(backend, role, accessor string, wrapped bool, withWrappedAccessor bool) string {
if wrapped && !withWrappedAccessor {
accessor = "wrapped-" + accessor
}
return fmt.Sprintf("backend=%s::role=%s::accessor=%s", strings.Trim(backend, "/"), strings.Trim(role, "/"), accessor)
Expand Down
84 changes: 77 additions & 7 deletions vault/resource_approle_auth_backend_role_secret_id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vault

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
Expand Down Expand Up @@ -39,14 +40,15 @@ func TestAccAppRoleAuthBackendRoleSecretID_basic(t *testing.T) {
func TestAccAppRoleAuthBackendRoleSecretID_wrapped(t *testing.T) {
backend := acctest.RandomWithPrefix("approle")
role := acctest.RandomWithPrefix("test-role")
withWrappedAccessor := false

resource.Test(t, resource.TestCase{
PreCheck: func() { testutil.TestAccPreCheck(t) },
Providers: testProviders,
CheckDestroy: testAccCheckAppRoleAuthBackendRoleSecretIDDestroy,
Steps: []resource.TestStep{
{
Config: testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role),
Config: testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role, withWrappedAccessor),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(secretIDResource, "backend", backend),
resource.TestCheckResourceAttr(secretIDResource, "role_name", role),
Expand All @@ -58,9 +60,69 @@ func TestAccAppRoleAuthBackendRoleSecretID_wrapped(t *testing.T) {
})
}

func TestAccAppRoleAuthBackendRoleSecretID_wrapped_withWrappedAccessor(t *testing.T) {
backend := acctest.RandomWithPrefix("approle")
role := acctest.RandomWithPrefix("test-role")
withWrappedAccessor := true

resource.Test(t, resource.TestCase{
PreCheck: func() { testutil.TestAccPreCheck(t) },
Providers: testProviders,
CheckDestroy: testAccCheckAppRoleAuthBackendRoleSecretIDDestroy,
Steps: []resource.TestStep{
{
Config: testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role, withWrappedAccessor),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(secretIDResource, "backend", backend),
resource.TestCheckResourceAttr(secretIDResource, "role_name", role),
resource.TestCheckResourceAttrSet(secretIDResource, "wrapping_accessor"),
resource.TestCheckResourceAttrSet(secretIDResource, "wrapping_token"),
resource.TestCheckResourceAttrSet(secretIDResource, "accessor"),
resource.TestMatchResourceAttr(secretIDResource, "accessor", regexp.MustCompile("^[[:xdigit:]]{8}-([[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$")),
),
},
},
})
}

func TestAccAppRoleAuthBackendRoleSecretID_wrapped_namespace(t *testing.T) {
backend := acctest.RandomWithPrefix("approle")
role := acctest.RandomWithPrefix("test-role")
withWrappedAccessor := false

namespacePath := acctest.RandomWithPrefix("test-namespace")
resource.Test(t, resource.TestCase{
PreCheck: func() { testutil.TestEntPreCheck(t) },
Providers: testProviders,
CheckDestroy: func(s *terraform.State) error {
if err := testAccCheckAppRoleAuthBackendRoleSecretIDDestroy(s); err != nil {
return err
}
return testNamespaceDestroy(namespacePath)(s)
},
Steps: []resource.TestStep{
{
Config: testNamespaceConfig(namespacePath),
Check: testNamespaceCheckAttrs(),
},
{
Config: testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped_namespace(namespacePath, backend, role, withWrappedAccessor),
Check: resource.ComposeTestCheckFunc(
testAssertClientNamespace(namespacePath),
resource.TestCheckResourceAttr(secretIDResource, "backend", backend),
resource.TestCheckResourceAttr(secretIDResource, "role_name", role),
resource.TestCheckResourceAttrSet(secretIDResource, "wrapping_accessor"),
resource.TestCheckResourceAttrSet(secretIDResource, "wrapping_token"),
),
},
},
})
}

func TestAccAppRoleAuthBackendRoleSecretID_wrapped_namespace_withWrappedAccessor(t *testing.T) {
backend := acctest.RandomWithPrefix("approle")
role := acctest.RandomWithPrefix("test-role")
withWrappedAccessor := true

namespacePath := acctest.RandomWithPrefix("test-namespace")
resource.Test(t, resource.TestCase{
Expand All @@ -78,13 +140,15 @@ func TestAccAppRoleAuthBackendRoleSecretID_wrapped_namespace(t *testing.T) {
Check: testNamespaceCheckAttrs(),
},
{
Config: testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped_namespace(namespacePath, backend, role),
Config: testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped_namespace(namespacePath, backend, role, withWrappedAccessor),
Check: resource.ComposeTestCheckFunc(
testAssertClientNamespace(namespacePath),
resource.TestCheckResourceAttr(secretIDResource, "backend", backend),
resource.TestCheckResourceAttr(secretIDResource, "role_name", role),
resource.TestCheckResourceAttrSet(secretIDResource, "wrapping_accessor"),
resource.TestCheckResourceAttrSet(secretIDResource, "wrapping_token"),
resource.TestCheckResourceAttrSet(secretIDResource, "accessor"),
resource.TestMatchResourceAttr(secretIDResource, "accessor", regexp.MustCompile("^[[:xdigit:]]{8}-([[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$")),
),
},
},
Expand Down Expand Up @@ -180,8 +244,8 @@ EOF
}`, backend, role, secretID)
}

func testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role string) string {
return fmt.Sprintf(`
func testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role string, withWrappedAccessor bool) string {
config := fmt.Sprintf(`
resource "vault_auth_backend" "approle" {
type = "approle"
path = "%s"
Expand All @@ -197,17 +261,23 @@ resource "vault_approle_auth_backend_role_secret_id" "secret_id" {
role_name = vault_approle_auth_backend_role.role.role_name
backend = vault_auth_backend.approle.path
wrapping_ttl = "60s"
}`, backend, role)
`, backend, role)
if withWrappedAccessor {
config += fmt.Sprintf(`
with_wrapped_accessor = %t
`, withWrappedAccessor)
}
return config + "}"
}

func testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped_namespace(namespacePath, backend, role string) string {
func testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped_namespace(namespacePath, backend, role string, withWrappedAccessor bool) string {
return fmt.Sprintf(`
provider "vault" {
namespace = %q
}
%s
`, namespacePath, testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role))
`, namespacePath, testAccAppRoleAuthBackendRoleSecretIDConfig_wrapped(backend, role, withWrappedAccessor))
}

func testAssertClientNamespace(expectedNS string) resource.TestCheckFunc {
Expand Down

0 comments on commit c324dc8

Please sign in to comment.