Skip to content

Commit

Permalink
Update transit secret key to support auto_rotate_period (hashicorp#1402)
Browse files Browse the repository at this point in the history
The provider originally shipped with support for the
auto_rotate_interval field, this was subsequently changed in the GA
release of Vault to be auto_rotate_period. This fix deprecates the
former and adds the latter.
  • Loading branch information
benashz authored and marcboudreau committed Nov 6, 2022
1 parent 811fb5b commit ae4d9eb
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 38 deletions.
66 changes: 56 additions & 10 deletions vault/resource_transit_secret_backend_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,19 @@ func transitSecretBackendKeyResource() *schema.Resource {
Default: false,
},
"auto_rotate_interval": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "Amount of time the key should live before being automatically rotated. A value of 0 disables automatic rotation for the key.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
Deprecated: "Use auto_rotate_period instead",
Description: "Amount of time the key should live before being automatically rotated. A value of 0 disables automatic rotation for the key.",
ConflictsWith: []string{"auto_rotate_period"},
},
"auto_rotate_period": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "Amount of time the key should live before being automatically rotated. A value of 0 disables automatic rotation for the key.",
ConflictsWith: []string{"auto_rotate_interval"},
},
"type": {
Type: schema.TypeString,
Expand Down Expand Up @@ -190,20 +199,21 @@ func transitSecretBackendKeyCreate(d *schema.ResourceData, meta interface{}) err

path := transitSecretBackendKeyPath(backend, name)

autoRotatePeriod := getTransitAutoRotatePeriod(d)
configData := map[string]interface{}{
"min_decryption_version": d.Get("min_decryption_version").(int),
"min_encryption_versoin": d.Get("min_encryption_version").(int),
"deletion_allowed": d.Get("deletion_allowed").(bool),
"exportable": d.Get("exportable").(bool),
"allow_plaintext_backup": d.Get("allow_plaintext_backup").(bool),
"auto_rotate_interval": d.Get("auto_rotate_interval").(int),
"auto_rotate_period": autoRotatePeriod,
}

data := map[string]interface{}{
"convergent_encryption": d.Get("convergent_encryption").(bool),
"derived": d.Get("derived").(bool),
"type": d.Get("type").(string),
"auto_rotate_interval": d.Get("auto_rotate_interval").(int),
"auto_rotate_period": autoRotatePeriod,
}

log.Printf("[DEBUG] Creating encryption key %s on transit secret backend %q", name, backend)
Expand All @@ -222,6 +232,22 @@ func transitSecretBackendKeyCreate(d *schema.ResourceData, meta interface{}) err
return transitSecretBackendKeyRead(d, meta)
}

func getTransitAutoRotatePeriod(d *schema.ResourceData) int {
var autoRotatePeriod int
v, ok := d.GetOkExists("auto_rotate_period")
if !ok {
if v, ok := d.GetOkExists("auto_rotate_interval"); ok {
log.Printf("[WARN] Using auto_rotate_internal to set auto_rotate_period, " +
"please use auto_rotate_period instead")
autoRotatePeriod = v.(int)
}
} else {
autoRotatePeriod = v.(int)
}

return autoRotatePeriod
}

func transitSecretBackendKeyRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*api.Client)

Expand Down Expand Up @@ -322,18 +348,38 @@ func transitSecretBackendKeyRead(d *schema.ResourceData, meta interface{}) error
}

fields := []string{
"allow_plaintext_backup", "auto_rotate_interval",
"allow_plaintext_backup",
"deletion_allowed", "derived", "exportable",
"supports_decryption", "supports_derivation",
"supports_encryption", "supports_signing", "type",
}

for _, k := range fields {
if err := d.Set(k, secret.Data[k]); err != nil {
set := func(f, k string) error {
v, ok := secret.Data[k]
if !ok {
log.Printf("[WARN] Expected key %q not found in response, path=%q", k, path)
}
if err := d.Set(f, v); err != nil {
return err
}
return nil
}

for _, f := range fields {
if err := set(f, f); err != nil {
return err
}
}

autoRotatePeriodField := "auto_rotate_period"
if _, ok := d.GetOkExists("auto_rotate_interval"); ok {
autoRotatePeriodField = "auto_rotate_interval"
}

if err := set(autoRotatePeriodField, "auto_rotate_period"); err != nil {
return nil
}

return nil
}

Expand All @@ -349,7 +395,7 @@ func transitSecretBackendKeyUpdate(d *schema.ResourceData, meta interface{}) err
"deletion_allowed": d.Get("deletion_allowed"),
"exportable": d.Get("exportable"),
"allow_plaintext_backup": d.Get("allow_plaintext_backup"),
"auto_rotate_interval": d.Get("auto_rotate_interval"),
"auto_rotate_period": getTransitAutoRotatePeriod(d),
}

_, err := client.Logical().Write(path+"/config", data)
Expand Down
70 changes: 43 additions & 27 deletions vault/resource_transit_secret_backend_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func TestTransitSecretBackendKey_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "backend", backend),
resource.TestCheckResourceAttr(resourceName, "name", name),
resource.TestCheckResourceAttr(resourceName, "deletion_allowed", "true"),
// auto_rotate_interval is deprecated,
// it will be updated to auto_rotate_period in the next step below
resource.TestCheckResourceAttr(resourceName, "auto_rotate_interval", "3600"),
resource.TestCheckResourceAttr(resourceName, "convergent_encryption", "false"),
resource.TestCheckResourceAttr(resourceName, "derived", "false"),
Expand All @@ -49,7 +51,7 @@ func TestTransitSecretBackendKey_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "backend", backend),
resource.TestCheckResourceAttr(resourceName, "name", name),
resource.TestCheckResourceAttr(resourceName, "deletion_allowed", "true"),
resource.TestCheckResourceAttr(resourceName, "auto_rotate_interval", "7200"),
resource.TestCheckResourceAttr(resourceName, "auto_rotate_period", "7200"),
resource.TestCheckResourceAttr(resourceName, "convergent_encryption", "false"),
resource.TestCheckResourceAttr(resourceName, "derived", "false"),
resource.TestCheckResourceAttrSet(resourceName, "keys.#"),
Expand All @@ -66,10 +68,25 @@ func TestTransitSecretBackendKey_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "allow_plaintext_backup", "true"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"auto_rotate_interval"},
},
{
Config: testTransitSecretBackendKeyConfig_invalidUpdates(name, backend),
ExpectError: regexp.MustCompile("cannot be disabled on a key that already has it enabled"),
},
{
Config: testTransitSecretBackendKeyConfig_conflicts(name, backend),
Destroy: false,
ExpectError: regexp.MustCompile("Error: Conflicting configuration arguments"),
},
{
Config: testTransitSecretBackendKeyConfig_updated(name, backend),
Destroy: true,
},
},
})
}
Expand Down Expand Up @@ -101,7 +118,7 @@ func TestTransitSecretBackendKey_rsa4096(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "supports_derivation", "false"),
resource.TestCheckResourceAttr(resourceName, "supports_encryption", "true"),
resource.TestCheckResourceAttr(resourceName, "supports_signing", "true"),
resource.TestCheckResourceAttr(resourceName, "auto_rotate_interval", "0"),
resource.TestCheckResourceAttr(resourceName, "auto_rotate_period", "0"),
),
},
{
Expand All @@ -119,35 +136,12 @@ func TestTransitSecretBackendKey_rsa4096(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "supports_derivation", "false"),
resource.TestCheckResourceAttr(resourceName, "supports_encryption", "true"),
resource.TestCheckResourceAttr(resourceName, "supports_signing", "true"),
resource.TestCheckResourceAttr(resourceName, "auto_rotate_interval", "0"),
resource.TestCheckResourceAttr(resourceName, "min_decryption_version", "1"),
resource.TestCheckResourceAttr(resourceName, "min_encryption_version", "1"),
resource.TestCheckResourceAttr(resourceName, "deletion_allowed", "true"),
resource.TestCheckResourceAttr(resourceName, "exportable", "true"),
resource.TestCheckResourceAttr(resourceName, "allow_plaintext_backup", "true"),
),
},
},
})
}

func TestTransitSecretBackendKey_import(t *testing.T) {
testutil.SkipTestEnvSet(t, testutil.EnvVarSkipVaultNext)

backend := acctest.RandomWithPrefix("transit")
name := acctest.RandomWithPrefix("key")
resourceName := "vault_transit_secret_backend_key.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testutil.TestAccPreCheck(t) },
Providers: testProviders,
CheckDestroy: testTransitSecretBackendKeyCheckDestroy,
Steps: []resource.TestStep{
{
Config: testTransitSecretBackendKeyConfig_basic(name, backend),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "backend", backend),
resource.TestCheckResourceAttr(resourceName, "name", name),
resource.TestCheckResourceAttrSet(resourceName, "keys.#"),
resource.TestCheckResourceAttr(resourceName, "auto_rotate_period", "0"),
),
},
{
Expand Down Expand Up @@ -224,7 +218,7 @@ resource "vault_transit_secret_backend_key" "test" {
min_decryption_version = 1
min_encryption_version = 1
deletion_allowed = true
auto_rotate_interval = 7200
auto_rotate_period = 7200
exportable = true
allow_plaintext_backup = true
}
Expand All @@ -250,6 +244,28 @@ resource "vault_transit_secret_backend_key" "test" {
`, path, name)
}

func testTransitSecretBackendKeyConfig_conflicts(name, path string) string {
return fmt.Sprintf(`
resource "vault_mount" "transit" {
path = "%s"
type = "transit"
}
resource "vault_transit_secret_backend_key" "test" {
backend = vault_mount.transit.path
name = "%s"
min_decryption_version = 1
min_encryption_version = 1
deletion_allowed = true
exportable = false
allow_plaintext_backup = false
# conflicts: auto_rotate_interval, auto_rotate_period
auto_rotate_interval = 3600
auto_rotate_period = 3600
}
`, path, name)
}

func testTransitSecretBackendKeyCheckDestroy(s *terraform.State) error {
client := testProvider.Meta().(*api.Client)

Expand Down
5 changes: 4 additions & 1 deletion website/docs/r/transit_secret_backend_key.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ The following arguments are supported:

* `min_encryption_version` - (Optional) Minimum key version to use for encryption

* `auto_rotate_interval` - (Optional) Amount of time the key should live before being automatically rotated.
* `auto_rotate_period` - (Optional) Amount of time the key should live before being automatically rotated.
A value of 0 disables automatic rotation for the key.

## Attributes Reference
Expand All @@ -78,6 +78,9 @@ The following arguments are supported:
* `supports_signing` - Whether or not the key supports signing, based on key type.


## Deprecations

* `auto_rotate_interval` - Replaced by `auto_rotate_period`.

## Import

Expand Down

0 comments on commit ae4d9eb

Please sign in to comment.