From 38a7250a65fc8d16518c44b2e322f9f5f3b9c9d8 Mon Sep 17 00:00:00 2001 From: vinay-gopalan <86625824+vinay-gopalan@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:17:43 -0800 Subject: [PATCH] Fix KVV2 datasource upon retrieval of soft deleted secrets (#1760) --- vault/data_source_kv_secret_v2.go | 6 ++- vault/data_source_kv_secret_v2_test.go | 65 ++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/vault/data_source_kv_secret_v2.go b/vault/data_source_kv_secret_v2.go index 05cf2287a..0ec0b29ed 100644 --- a/vault/data_source_kv_secret_v2.go +++ b/vault/data_source_kv_secret_v2.go @@ -137,8 +137,10 @@ func kvSecretV2DataSourceRead(_ context.Context, d *schema.ResourceData, meta in return diag.FromErr(err) } - if err := d.Set(consts.FieldData, serializeDataMapToString(data.(map[string]interface{}))); err != nil { - return diag.FromErr(err) + if v, ok := data.(map[string]interface{}); ok { + if err := d.Set(consts.FieldData, serializeDataMapToString(v)); err != nil { + return diag.FromErr(err) + } } if v, ok := secret.Data["metadata"]; ok { diff --git a/vault/data_source_kv_secret_v2_test.go b/vault/data_source_kv_secret_v2_test.go index 5fac5839e..70a095d04 100644 --- a/vault/data_source_kv_secret_v2_test.go +++ b/vault/data_source_kv_secret_v2_test.go @@ -9,8 +9,10 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/vault/api" "github.com/hashicorp/terraform-provider-vault/internal/consts" + "github.com/hashicorp/terraform-provider-vault/internal/provider" "github.com/hashicorp/terraform-provider-vault/testutil" ) @@ -59,6 +61,60 @@ func TestDataSourceKVV2Secret(t *testing.T) { }) } +func TestDataSourceKVV2Secret_deletedSecret(t *testing.T) { + mount := acctest.RandomWithPrefix("tf-kv") + name := acctest.RandomWithPrefix("foo") + + resource.Test(t, resource.TestCase{ + Providers: testProviders, + PreCheck: func() { testutil.TestAccPreCheck(t) }, + Steps: []resource.TestStep{ + { + PreConfig: func() { + client := testProvider.Meta().(*provider.ProviderMeta).GetClient() + + err := client.Sys().Mount(mount, &api.MountInput{ + Type: "kv-v2", + Description: "Mount for testing KV datasource", + }) + if err != nil { + t.Fatalf(fmt.Sprintf("error mounting kvv2 engine; err=%s", err)) + } + + m := map[string]interface{}{ + "foo": "bar", + "baz": "qux", + } + + data := map[string]interface{}{ + consts.FieldData: m, + } + + // Write data at path + path := fmt.Sprintf("%s/data/%s", mount, name) + resp, err := client.Logical().Write(path, data) + if err != nil { + t.Fatalf(fmt.Sprintf("error writing to Vault; err=%s", err)) + } + + if resp == nil { + t.Fatalf("empty response") + } + + // Soft Delete KV V2 secret at path + // Secret data returned from Vault is nil + // confirm that plan does not result in panic + _, err = client.Logical().Delete(path) + if err != nil { + } + }, + Config: kvV2DatasourceConfig(mount, name), + PlanOnly: true, + }, + }, + }) +} + func testDataSourceKVV2SecretConfig(mount, name string) string { return fmt.Sprintf(` %s @@ -113,3 +169,12 @@ data "vault_kv_secret_v2" "test" { version = 1 }`, kvV2MountConfig(mount), name) } + +func kvV2DatasourceConfig(mount, name string) string { + return fmt.Sprintf(` +data "vault_kv_secret_v2" "test" { + mount = "%s" + name = "%s" +} +`, mount, name) +}