Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added expiration date field to ibm_kms_key resource #1967

Merged
merged 6 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions ibm/resource_ibm_kms_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ func resourceIBMKmskey() *schema.Resource {
Computed: true,
Description: "Crn of the key",
},
"expiration_date": {
Type: schema.TypeString,
Optional: true,
Description: "The date the key material expires. The date format follows RFC 3339. You can set an expiration date on any key on its creation. A key moves into the Deactivated state within one hour past its expiration date, if one is assigned. If you create a key without specifying an expiration date, the key does not expire",
ForceNew: true,
},
ResourceName: {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -186,12 +192,25 @@ func resourceIBMKmsKeyCreate(d *schema.ResourceData, meta interface{}) error {
name := d.Get("key_name").(string)
standardKey := d.Get("standard_key").(bool)

var expiration *time.Time
if es, ok := d.GetOk("expiration_date"); ok {
expiration_string := es.(string)
// parse string to required time format
expiration_time, err := time.Parse(time.RFC3339, expiration_string)
if err != nil {
return fmt.Errorf("Invalid time format (the date format follows RFC 3339): %s", err)
}
expiration = &expiration_time
} else {
expiration = nil
}

var keyCRN string
if standardKey {
if v, ok := d.GetOk("payload"); ok {
//import standard key
payload := v.(string)
stkey, err := kpAPI.CreateImportedStandardKey(context.Background(), name, nil, payload)
stkey, err := kpAPI.CreateImportedStandardKey(context.Background(), name, expiration, payload)
if err != nil {
return fmt.Errorf(
"Error while creating standard key with payload: %s", err)
Expand All @@ -200,7 +219,7 @@ func resourceIBMKmsKeyCreate(d *schema.ResourceData, meta interface{}) error {
keyCRN = stkey.CRN
} else {
//create standard key
stkey, err := kpAPI.CreateStandardKey(context.Background(), name, nil)
stkey, err := kpAPI.CreateStandardKey(context.Background(), name, expiration)
if err != nil {
return fmt.Errorf(
"Error while creating standard key: %s", err)
Expand All @@ -214,15 +233,15 @@ func resourceIBMKmsKeyCreate(d *schema.ResourceData, meta interface{}) error {
payload := v.(string)
encryptedNonce := d.Get("encrypted_nonce").(string)
iv := d.Get("iv_value").(string)
stkey, err := kpAPI.CreateImportedRootKey(context.Background(), name, nil, payload, encryptedNonce, iv)
stkey, err := kpAPI.CreateImportedRootKey(context.Background(), name, expiration, payload, encryptedNonce, iv)
if err != nil {
return fmt.Errorf(
"Error while creating Root key with payload: %s", err)
}
log.Printf("New key created: %v", *stkey)
keyCRN = stkey.CRN
} else {
stkey, err := kpAPI.CreateRootKey(context.Background(), name, nil)
stkey, err := kpAPI.CreateRootKey(context.Background(), name, expiration)
if err != nil {
return fmt.Errorf(
"Error while creating Root key: %s", err)
Expand Down Expand Up @@ -304,6 +323,7 @@ func resourceIBMKmsKeyRead(d *schema.ResourceData, meta interface{}) error {
d.Set("endpoint_type", endpointType)
d.Set("type", instanceType)
d.Set("force_delete", d.Get("force_delete").(bool))
d.Set("expiration_date", key.Expiration)
d.Set(ResourceName, key.Name)
d.Set(ResourceCRN, key.CRN)
d.Set(ResourceStatus, key.State)
Expand Down
100 changes: 100 additions & 0 deletions ibm/resource_ibm_kms_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package ibm

import (
"fmt"
"math/rand"
"regexp"
"testing"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
Expand Down Expand Up @@ -48,6 +51,65 @@ func TestAccIBMKMSResource_basic(t *testing.T) {
})
}

// Test for valid expiration date for create key operation
func TestAccIBMKMSResource_ValidExpDate(t *testing.T) {

instanceName := fmt.Sprintf("kms_%d", acctest.RandIntRange(10, 100))
keyName := fmt.Sprintf("key_%d", acctest.RandIntRange(10, 100))

hours := time.Duration(rand.Intn(24) + 1)
mins := time.Duration(rand.Intn(60) + 1)
sec := time.Duration(rand.Intn(60) + 1)
expirationDateValid := ((time.Now().Add(time.Hour*hours + time.Minute*mins + time.Second*sec)).Format(time.RFC3339))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckIBMKmsCreateStandardKeyConfig(instanceName, keyName, expirationDateValid),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("ibm_kms_key.test", "key_name", keyName),
resource.TestCheckResourceAttr("ibm_kms_key.test", "expiration_date", expirationDateValid),
),
},
resource.TestStep{
Config: testAccCheckIBMKmsCreateRootKeyConfig(instanceName, keyName, expirationDateValid),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("ibm_kms_key.test", "key_name", keyName),
resource.TestCheckResourceAttr("ibm_kms_key.test", "expiration_date", expirationDateValid),
),
},
},
})
}

// Test for invalid expiration date for create key operation
func TestAccIBMKMSResource_InvalidExpDate(t *testing.T) {
instanceName := fmt.Sprintf("kms_%d", acctest.RandIntRange(10, 100))
keyName := fmt.Sprintf("key_%d", acctest.RandIntRange(10, 100))

hours := time.Duration(rand.Intn(24) + 1)
mins := time.Duration(rand.Intn(60) + 1)
sec := time.Duration(rand.Intn(60) + 1)
expirationDateInvalid := (time.Now().Add(time.Hour*hours + time.Minute*mins + time.Second*sec)).String()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckIBMKmsCreateStandardKeyConfig(instanceName, keyName, expirationDateInvalid),
ExpectError: regexp.MustCompile("Invalid time format"),
},
resource.TestStep{
Config: testAccCheckIBMKmsCreateRootKeyConfig(instanceName, keyName, expirationDateInvalid),
ExpectError: regexp.MustCompile("Invalid time format"),
},
},
})
}

func testAccCheckIBMKmsResourceStandardConfig(instanceName, KeyName string) string {
return fmt.Sprintf(`
resource "ibm_resource_instance" "kms_instance" {
Expand Down Expand Up @@ -139,3 +201,41 @@ func testAccCheckIBMKmsResourceHpcsConfig(hpcsInstanceID, KeyName string) string

`, hpcsInstanceID, KeyName)
}

func testAccCheckIBMKmsCreateStandardKeyConfig(instanceName, KeyName, expirationDate string) string {
return fmt.Sprintf(`
resource "ibm_resource_instance" "kms_instance" {
name = "%s"
service = "kms"
plan = "tiered-pricing"
location = "us-south"
}
resource "ibm_kms_key" "test" {
instance_id = "${ibm_resource_instance.kms_instance.guid}"
key_name = "%s"
standard_key = true
force_delete = true
expiration_date = "%s"
}

`, instanceName, KeyName, expirationDate)
}

func testAccCheckIBMKmsCreateRootKeyConfig(instanceName, KeyName, expirationDate string) string {
return fmt.Sprintf(`
resource "ibm_resource_instance" "kms_instance" {
name = "%s"
service = "kms"
plan = "tiered-pricing"
location = "us-south"
}
resource "ibm_kms_key" "test" {
instance_id = "${ibm_resource_instance.kms_instance.guid}"
key_name = "%s"
standard_key = false
force_delete = true
expiration_date = "%s"
}

`, instanceName, KeyName, expirationDate)
}
2 changes: 2 additions & 0 deletions website/docs/r/kms_key.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ The following arguments are supported:
* `iv_value` - (Optional, Forces new resource, string) Used with import tokens. The initialization vector (IV) that is generated when you encrypt a nonce. The IV value is required to decrypt the encrypted nonce value that you provide when you make a key import request to the service. To generate an IV, encrypt the nonce by running `ibmcloud kp import-token encrypt-nonce`. Only for imported root key.
* `force_delete` - (Optional, bool) If set to true, Key Protect forces deletion on a key that is protecting a cloud resource, such as a Cloud Object Storage bucket. The action removes any registrations that are associated with the key. Note: If a key is protecting a cloud resource that has a retention policy, Key Protect cannot delete the key. Default: false.
**NOTE**: Before doing terraform destroy if force_delete flag is introduced after provisioning keys, a terraform apply must be done before terraform destroy for force_delete flag to take effect.
* `expiration_date` - (Optional, Forces new resource, string) The date the key material expires. The date format follows RFC 3339. You can set an expiration date on any key on its creation. A key moves into the Deactivated state within one hour past its expiration date, if one is assigned. If you create a key without specifying an expiration date, the key does not expire
`Example: 2018-12-01T23:20:50.52Z`.


## Attribute Reference
Expand Down