Skip to content

Commit 6f317a4

Browse files
committed
Support for KMS Key deletion
1 parent efbb9bc commit 6f317a4

File tree

7 files changed

+116
-3
lines changed

7 files changed

+116
-3
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
## 3.29.1 (Unreleased)
1+
## 3.30.1 (Unreleased)
2+
## 3.30.0 (June 19, 2019)
3+
4+
### Added
5+
- Support for scheduling KMS key deletion
6+
27
## 3.29.0 (June 12, 2019)
38

49
### Added

oci/kms_key_data_source.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ func (s *KmsKeyDataSourceCrud) SetData() error {
107107
s.D.Set("time_created", s.Res.TimeCreated.String())
108108
}
109109

110+
if s.Res.TimeOfDeletion != nil {
111+
s.D.Set("time_of_deletion", *s.Res.TimeOfDeletion)
112+
}
113+
110114
if s.Res.VaultId != nil {
111115
s.D.Set("vault_id", *s.Res.VaultId)
112116
}

oci/kms_key_resource.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package provider
55
import (
66
"context"
77
"fmt"
8+
"time"
89

910
"github.com/hashicorp/terraform/helper/schema"
1011

@@ -13,6 +14,7 @@ import (
1314
"strings"
1415

1516
"github.com/hashicorp/terraform/helper/validation"
17+
oci_common "github.com/oracle/oci-go-sdk/common"
1618
oci_kms "github.com/oracle/oci-go-sdk/keymanagement"
1719
)
1820

@@ -92,6 +94,11 @@ func KmsKeyResource() *schema.Resource {
9294
"DISABLED",
9395
}, false),
9496
},
97+
"time_of_deletion": {
98+
Type: schema.TypeString,
99+
Computed: true,
100+
Optional: true,
101+
},
95102

96103
// Computed
97104
"current_key_version": {
@@ -174,7 +181,19 @@ func updateKmsKey(d *schema.ResourceData, m interface{}) error {
174181
}
175182

176183
func deleteKmsKey(d *schema.ResourceData, m interface{}) error {
177-
return nil
184+
sync := &KmsKeyResourceCrud{}
185+
sync.D = d
186+
endpoint, ok := d.GetOkExists("management_endpoint")
187+
if !ok {
188+
return fmt.Errorf("management endpoint missing")
189+
}
190+
client, err := m.(*OracleClients).KmsManagementClient(endpoint.(string))
191+
if err != nil {
192+
return err
193+
}
194+
sync.Client = client
195+
196+
return DeleteResource(d, sync)
178197
}
179198

180199
type KmsKeyResourceCrud struct {
@@ -362,6 +381,25 @@ func (s *KmsKeyResourceCrud) Update() error {
362381
return nil
363382
}
364383

384+
func (s *KmsKeyResourceCrud) Delete() error {
385+
request := oci_kms.ScheduleKeyDeletionRequest{}
386+
387+
if timeOfDeletion, ok := s.D.GetOkExists("time_of_deletion"); ok {
388+
tmpTime, err := time.Parse(time.RFC3339Nano, timeOfDeletion.(string))
389+
if err != nil {
390+
return err
391+
}
392+
request.TimeOfDeletion = &oci_common.SDKTime{Time: tmpTime}
393+
}
394+
395+
request.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "kms")
396+
tmp := s.D.Id()
397+
request.KeyId = &tmp
398+
399+
_, err := s.Client.ScheduleKeyDeletion(context.Background(), request)
400+
return err
401+
}
402+
365403
func (s *KmsKeyResourceCrud) SetData() error {
366404
if s.Res.CompartmentId != nil {
367405
s.D.Set("compartment_id", *s.Res.CompartmentId)
@@ -395,6 +433,10 @@ func (s *KmsKeyResourceCrud) SetData() error {
395433
s.D.Set("time_created", s.Res.TimeCreated.String())
396434
}
397435

436+
if s.Res.TimeOfDeletion != nil {
437+
s.D.Set("time_of_deletion", *s.Res.TimeOfDeletion)
438+
}
439+
398440
if s.Res.VaultId != nil {
399441
s.D.Set("vault_id", *s.Res.VaultId)
400442
}

oci/kms_key_test.go

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
package provider
44

55
import (
6+
"context"
67
"fmt"
78
"testing"
9+
"time"
810

911
"github.com/hashicorp/terraform/helper/resource"
1012
"github.com/hashicorp/terraform/terraform"
13+
"github.com/oracle/oci-go-sdk/common"
1114

15+
oci_kms "github.com/oracle/oci-go-sdk/keymanagement"
1216
"github.com/terraform-providers/terraform-provider-oci/httpreplay"
1317
)
1418

@@ -33,6 +37,8 @@ var (
3337
"values": Representation{repType: Required, create: []string{`${oci_kms_key.test_key.id}`}},
3438
}
3539

40+
deletionTime = time.Now().UTC().AddDate(0, 0, 8).Truncate(time.Millisecond)
41+
3642
keyRepresentation = map[string]interface{}{
3743
"compartment_id": Representation{repType: Required, create: `${var.tenancy_ocid}`},
3844
"display_name": Representation{repType: Required, create: `Key C`, update: `displayName2`},
@@ -41,6 +47,7 @@ var (
4147
"desired_state": Representation{repType: Optional, create: `ENABLED`, update: `DISABLED`},
4248
"defined_tags": Representation{repType: Optional, create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
4349
"freeform_tags": Representation{repType: Optional, create: map[string]string{"bar-key": "value"}, update: map[string]string{"Department": "Accounting"}},
50+
"time_of_deletion": Representation{repType: Optional, create: deletionTime.Format(time.RFC3339Nano)},
4451
}
4552
keyKeyShapeRepresentation = map[string]interface{}{
4653
"algorithm": Representation{repType: Required, create: `AES`},
@@ -91,7 +98,8 @@ func TestKmsKeyResource_basic(t *testing.T) {
9198
var resId, resId2 string
9299

93100
resource.Test(t, resource.TestCase{
94-
PreCheck: func() { testAccPreCheck(t) },
101+
PreCheck: func() { testAccPreCheck(t) },
102+
CheckDestroy: testAccCheckKMSKeyDestroy,
95103
Providers: map[string]terraform.ResourceProvider{
96104
"oci": provider,
97105
},
@@ -241,13 +249,63 @@ func TestKmsKeyResource_basic(t *testing.T) {
241249
ImportStateIdFunc: keyImportId,
242250
ImportStateVerifyIgnore: []string{
243251
"desired_state",
252+
"time_of_deletion",
244253
},
245254
ResourceName: resourceName,
246255
},
247256
},
248257
})
249258
}
250259

260+
func testAccCheckKMSKeyDestroy(s *terraform.State) error {
261+
noResourceFound := true
262+
for _, rs := range s.RootModule().Resources {
263+
if rs.Type == "oci_kms_key" {
264+
client, err := testAccProvider.Meta().(*OracleClients).KmsManagementClient(rs.Primary.Attributes["management_endpoint"])
265+
if err != nil {
266+
return err
267+
}
268+
269+
noResourceFound = false
270+
request := oci_kms.GetKeyRequest{}
271+
272+
tmp := rs.Primary.ID
273+
request.KeyId = &tmp
274+
275+
request.RequestMetadata.RetryPolicy = getRetryPolicy(true, "kms")
276+
277+
response, err := client.GetKey(context.Background(), request)
278+
279+
if err == nil {
280+
deletedLifecycleStates := map[string]bool{
281+
string(oci_kms.KeyLifecycleStateSchedulingDeletion): true,
282+
string(oci_kms.KeyLifecycleStatePendingDeletion): true,
283+
}
284+
if _, ok := deletedLifecycleStates[string(response.LifecycleState)]; !ok {
285+
//resource lifecycle state is not in expected deleted lifecycle states.
286+
return fmt.Errorf("resource lifecycle state: %s is not in expected deleted lifecycle states", response.LifecycleState)
287+
}
288+
289+
if !response.TimeOfDeletion.Equal(deletionTime) && !httpreplay.ModeRecordReplay() {
290+
return fmt.Errorf("resource time_of_deletion: %s is not set to %s", response.TimeOfDeletion.Format(time.RFC3339Nano), deletionTime.Format(time.RFC3339Nano))
291+
}
292+
//resource lifecycle state is in expected deleted lifecycle states. continue with next one.
293+
continue
294+
}
295+
296+
//Verify that exception is for '404 not found'.
297+
if failure, isServiceError := common.IsServiceError(err); !isServiceError || failure.GetHTTPStatusCode() != 404 {
298+
return err
299+
}
300+
}
301+
}
302+
if noResourceFound {
303+
return fmt.Errorf("at least one resource was expected from the state file, but could not be found")
304+
}
305+
306+
return nil
307+
}
308+
251309
func keyImportId(state *terraform.State) (string, error) {
252310
for _, rs := range state.RootModule().Resources {
253311
if rs.Type == "oci_kms_key" {

website/docs/d/kms_key.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ The following attributes are exported:
4545
* `length` - The length of the key, expressed as an integer. Values of 16, 24, or 32 are supported.
4646
* `state` - The key's current state. Example: `ENABLED`
4747
* `time_created` - The date and time the key was created, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-04-03T21:10:29.600Z`
48+
* `time_of_deletion` - An optional property for the deletion time of the key, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2019-04-03T21:10:29.600Z`
4849
* `vault_id` - The OCID of the vault that contains this key.
4950

website/docs/d/kms_keys.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ The following attributes are exported:
5151
* `length` - The length of the key, expressed as an integer. Values of 16, 24, or 32 are supported.
5252
* `state` - The key's current state. Example: `ENABLED`
5353
* `time_created` - The date and time the key was created, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-04-03T21:10:29.600Z`
54+
* `time_of_deletion` - An optional property for the deletion time of the key, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2019-04-03T21:10:29.600Z`
5455
* `vault_id` - The OCID of the vault that contains this key.
5556

website/docs/r/kms_key.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ The following arguments are supported:
4444
* `algorithm` - (Required) The algorithm used by a key's KeyVersions to encrypt or decrypt.
4545
* `length` - (Required) The length of the key, expressed as an integer. Values of 16, 24, or 32 are supported.
4646
* `management_endpoint` - (Required) The service endpoint to perform management operations against. Management operations include 'Create,' 'Update,' 'List,' 'Get,' and 'Delete' operations. See Vault Management endpoint.
47+
* `time_of_deletion` - (Required) (Updatable) An optional property for the deletion time of the key, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2019-04-03T21:10:29.600Z`
4748

4849

4950
** IMPORTANT **
@@ -64,6 +65,7 @@ The following attributes are exported:
6465
* `length` - The length of the key, expressed as an integer. Values of 16, 24, or 32 are supported.
6566
* `state` - The key's current state. Example: `ENABLED`
6667
* `time_created` - The date and time the key was created, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2018-04-03T21:10:29.600Z`
68+
* `time_of_deletion` - An optional property for the deletion time of the key, expressed in [RFC 3339](https://tools.ietf.org/html/rfc3339) timestamp format. Example: `2019-04-03T21:10:29.600Z`
6769
* `vault_id` - The OCID of the vault that contains this key.
6870

6971
## Import

0 commit comments

Comments
 (0)