Skip to content

Commit 8a9ea81

Browse files
committed
add resoure resource_tc_kms_external_key
1 parent e60c329 commit 8a9ea81

File tree

2 files changed

+439
-0
lines changed

2 files changed

+439
-0
lines changed
Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
/*
2+
Provide a resource to create a KMS external import key.
3+
4+
Example Usage
5+
6+
```hcl
7+
resource "tencentcloud_kms_external_key" "foo" {
8+
alias = "test"
9+
description = "describe key test message."
10+
wrapping_algorithm = "RSAES_PKCS1_V1_5"
11+
key_material_base64 = "MTIzMTIzMTIzMTIzMTIzQQ=="
12+
valid_to = 2147443200
13+
}
14+
```
15+
16+
Import
17+
18+
KMS external keys can be imported using the id, e.g.
19+
20+
```
21+
$ terraform import tencentcloud_kms_external_key.foo 287e8f40-7cbb-11eb-9a3a-5254004f7f94
22+
```
23+
*/
24+
package tencentcloud
25+
26+
import (
27+
"context"
28+
"log"
29+
30+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
31+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
32+
kms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms/v20190118"
33+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
34+
)
35+
36+
func resourceTencentCloudKmsExternalKey() *schema.Resource {
37+
return &schema.Resource{
38+
Create: resourceTencentCloudKmsExternalKeyCreate,
39+
Read: resourceTencentCloudKmsExternalKeyRead,
40+
Update: resourceTencentCloudKmsExternalKeyUpdate,
41+
Delete: resourceTencentCloudKmsExternalKeyDelete,
42+
Importer: &schema.ResourceImporter{
43+
State: schema.ImportStatePassthrough,
44+
},
45+
46+
Schema: map[string]*schema.Schema{
47+
"key_id": {
48+
Type: schema.TypeString,
49+
Optional: true,
50+
Computed: true,
51+
Description: "ID of CMK.",
52+
},
53+
"alias": {
54+
Type: schema.TypeString,
55+
Required: true,
56+
ValidateFunc: validateStringLengthInRange(1, 60),
57+
Description: "Name of CMK.The name can only contain English letters, numbers, underscore and hyphen '-'.The first character must be a letter or number.",
58+
},
59+
"description": {
60+
Type: schema.TypeString,
61+
Optional: true,
62+
Computed: true,
63+
Description: "Description of CMK.The maximum is 1024 bytes.",
64+
},
65+
"key_state": {
66+
Type: schema.TypeString,
67+
Optional: true,
68+
ValidateFunc: validateAllowedStringValue(KMS_KEY_STATE),
69+
Computed: true,
70+
Description: "State of CMK.Available values include `Enabled`, `Disabled`, `PendingDelete`, `PendingImport`, `Archived`.",
71+
},
72+
"pending_delete_window_in_days": {
73+
Type: schema.TypeInt,
74+
Optional: true,
75+
Default: 7,
76+
ValidateFunc: validateIntegerInRange(7, 30),
77+
Description: "Duration in days after which the key is deleted after destruction of the resource, must be between 7 and 30 days. Defaults to 7 days.",
78+
},
79+
"wrapping_algorithm": {
80+
Type: schema.TypeString,
81+
Optional: true,
82+
Default: KMS_WRAPPING_ALGORITHM_RSAES_PKCS1_V1_5,
83+
ValidateFunc: validateAllowedStringValue(KMS_WRAPPING_ALGORITHM),
84+
Description: "The algorithm for encrypting key material.Available values include `RSAES_PKCS1_V1_5`, `RSAES_OAEP_SHA_1` and `RSAES_OAEP_SHA_256`.",
85+
},
86+
"key_material_base64": {
87+
Type: schema.TypeString,
88+
Optional: true,
89+
Sensitive: true,
90+
Description: "The base64-encoded key material encrypted with the public_key.For regions using the national secret version, the length of the imported key material is required to be 128 bits, and for regions using the FIPS version, the length of the imported key material is required to be 256 bits。",
91+
},
92+
"valid_to": {
93+
Type: schema.TypeInt,
94+
Optional: true,
95+
Computed: true,
96+
Description: "this value means the effective timestamp of the key material, 0 means it does not expire.Need to be greater than the current time point, the maximum support is 2147443200.",
97+
},
98+
"tags": {
99+
Type: schema.TypeMap,
100+
Optional: true,
101+
Computed: true,
102+
Description: "Tags of CMK.",
103+
},
104+
},
105+
}
106+
}
107+
108+
func resourceTencentCloudKmsExternalKeyCreate(d *schema.ResourceData, meta interface{}) error {
109+
defer logElapsed("resource.tencentcloud_kms_external_key.create")()
110+
111+
logId := getLogId(contextNil)
112+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
113+
kmsService := KmsService{
114+
client: meta.(*TencentCloudClient).apiV3Conn,
115+
}
116+
117+
keyType := KMS_ORIGIN_TYPE[KMS_ORIGIN_EXTERNAL]
118+
alias := d.Get("alias").(string)
119+
description := ""
120+
keyUsage := KMS_KEY_USAGE_ENCRYPT_DECRYPT
121+
if v, ok := d.GetOk("description"); ok {
122+
description = v.(string)
123+
}
124+
125+
var keyId string
126+
var outErr, inErr error
127+
outErr = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
128+
keyId, inErr = kmsService.CreateKey(ctx, keyType, alias, description, keyUsage)
129+
if inErr != nil {
130+
return retryError(inErr)
131+
}
132+
return nil
133+
})
134+
if outErr != nil {
135+
log.Printf("[CRITAL]%s create KMS key failed, reason:%+v", logId, outErr)
136+
return outErr
137+
}
138+
d.SetId(keyId)
139+
_ = d.Set("key_id", helper.String(keyId))
140+
141+
if v, ok := d.GetOk("key_material_base64"); ok {
142+
param := make(map[string]interface{})
143+
param["key_id"] = keyId
144+
param["algorithm"] = d.Get("wrapping_algorithm").(string)
145+
param["key_spec"] = KMS_WRAPPING_KEY_SPEC_RSA_2048
146+
param["key_material_base64"] = v.(string)
147+
param["valid_to"] = d.Get("valid_to").(int)
148+
149+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
150+
e := kmsService.ImportKeyMaterial(ctx, param)
151+
if e != nil {
152+
return retryError(e)
153+
}
154+
return nil
155+
})
156+
if err != nil {
157+
log.Printf("[CRITAL]%s Create KMS external key failed, reason:%+v", logId, err)
158+
return err
159+
}
160+
}
161+
162+
if keyState := d.Get("key_state").(string); keyState == KMS_KEY_STATE_DISABLED {
163+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
164+
e := kmsService.DisableKey(ctx, d.Id())
165+
if e != nil {
166+
return retryError(e)
167+
}
168+
return nil
169+
})
170+
if err != nil {
171+
log.Printf("[CRITAL]%s modify KMS key state failed, reason:%+v", logId, err)
172+
return err
173+
}
174+
}
175+
176+
if tags := helper.GetTags(d, "tags"); len(tags) > 0 {
177+
tcClient := meta.(*TencentCloudClient).apiV3Conn
178+
tagService := &TagService{client: tcClient}
179+
keyMetaData, err := kmsService.DescribeKeyById(ctx, keyId)
180+
if err != nil {
181+
return err
182+
}
183+
resourceName := BuildTagResourceName("kms", "key", tcClient.Region, *keyMetaData.ResourceId)
184+
if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil {
185+
return err
186+
}
187+
}
188+
189+
return resourceTencentCloudKmsExternalKeyRead(d, meta)
190+
}
191+
192+
func resourceTencentCloudKmsExternalKeyRead(d *schema.ResourceData, meta interface{}) error {
193+
defer logElapsed("resource.tencentcloud_kms_external_key.read")()
194+
defer inconsistentCheck(d, meta)()
195+
196+
logId := getLogId(contextNil)
197+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
198+
199+
keyId := d.Id()
200+
kmsService := &KmsService{
201+
client: meta.(*TencentCloudClient).apiV3Conn,
202+
}
203+
var key *kms.KeyMetadata
204+
err := resource.Retry(readRetryTimeout, func() *resource.RetryError {
205+
result, e := kmsService.DescribeKeyById(ctx, keyId)
206+
if e != nil {
207+
return retryError(e)
208+
}
209+
key = result
210+
return nil
211+
})
212+
if err != nil {
213+
log.Printf("[CRITAL]%s read KMS external key failed, reason:%+v", logId, err)
214+
return err
215+
}
216+
217+
if key == nil {
218+
d.SetId("")
219+
return nil
220+
}
221+
222+
_ = d.Set("key_id", key.KeyId)
223+
_ = d.Set("alias", key.Alias)
224+
_ = d.Set("description", key.Description)
225+
_ = d.Set("key_state", key.KeyState)
226+
tcClient := meta.(*TencentCloudClient).apiV3Conn
227+
tagService := &TagService{client: tcClient}
228+
tags, err := tagService.DescribeResourceTags(ctx, "kms", "key", tcClient.Region, *key.ResourceId)
229+
if err != nil {
230+
return err
231+
}
232+
_ = d.Set("tags", tags)
233+
return nil
234+
}
235+
236+
func resourceTencentCloudKmsExternalKeyUpdate(d *schema.ResourceData, meta interface{}) error {
237+
defer logElapsed("resource.tencentcloud_kms_external_key.update")()
238+
239+
logId := getLogId(contextNil)
240+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
241+
keyId := d.Id()
242+
kmsService := KmsService{
243+
client: meta.(*TencentCloudClient).apiV3Conn,
244+
}
245+
246+
if d.HasChange("description") {
247+
description := d.Get("description").(string)
248+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
249+
e := kmsService.UpdateKeyDescription(ctx, keyId, description)
250+
if e != nil {
251+
return retryError(e)
252+
}
253+
return nil
254+
})
255+
if err != nil {
256+
log.Printf("[CRITAL]%s modify KMS external key description failed, reason:%+v", logId, err)
257+
return err
258+
}
259+
}
260+
261+
if d.HasChange("alias") {
262+
alias := d.Get("alias").(string)
263+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
264+
e := kmsService.UpdateKeyAlias(ctx, keyId, alias)
265+
if e != nil {
266+
return retryError(e)
267+
}
268+
return nil
269+
})
270+
if err != nil {
271+
log.Printf("[CRITAL]%s modify KMS external key alias failed, reason:%+v", logId, err)
272+
return err
273+
}
274+
}
275+
276+
if d.HasChange("key_material_base64") || d.HasChange("valid_to") {
277+
err := updateKeyMaterial(ctx, kmsService, d)
278+
if err != nil {
279+
log.Printf("[CRITAL]%s import KMS external key material key failed, reason:%+v", logId, err)
280+
return err
281+
}
282+
}
283+
284+
if d.HasChange("key_state") {
285+
oldKeyState, newKeyState := d.GetChange("key_state")
286+
err := updateKeyState(ctx, kmsService, keyId, oldKeyState.(string), newKeyState.(string))
287+
if err != nil {
288+
log.Printf("[CRITAL]%s modify KMS key state failed, reason:%+v", logId, err)
289+
return err
290+
}
291+
}
292+
293+
if d.HasChange("tags") {
294+
tcClient := meta.(*TencentCloudClient).apiV3Conn
295+
tagService := &TagService{client: tcClient}
296+
297+
oldValue, newValue := d.GetChange("tags")
298+
replaceTags, deleteTags := diffTags(oldValue.(map[string]interface{}), newValue.(map[string]interface{}))
299+
keyMetaData, err := kmsService.DescribeKeyById(ctx, keyId)
300+
if err != nil {
301+
return err
302+
}
303+
resourceName := BuildTagResourceName("kms", "key", tcClient.Region, *keyMetaData.ResourceId)
304+
if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil {
305+
return err
306+
}
307+
}
308+
309+
return resourceTencentCloudKmsKeyRead(d, meta)
310+
}
311+
312+
func resourceTencentCloudKmsExternalKeyDelete(d *schema.ResourceData, meta interface{}) error {
313+
defer logElapsed("resource.tencentcloud_kms_external_key.delete")()
314+
315+
logId := getLogId(contextNil)
316+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
317+
kmsService := KmsService{
318+
client: meta.(*TencentCloudClient).apiV3Conn,
319+
}
320+
321+
keyId := d.Id()
322+
pendingDeleteWindowInDays := d.Get("pending_delete_window_in_days").(int)
323+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
324+
e := kmsService.DeleteKey(ctx, keyId, uint64(pendingDeleteWindowInDays))
325+
if e != nil {
326+
return retryError(e)
327+
}
328+
return nil
329+
})
330+
if err != nil {
331+
log.Printf("[CRITAL]%s delete KMS key failed, reason:%+v", logId, err)
332+
return err
333+
}
334+
335+
return resourceTencentCloudKmsKeyRead(d, meta)
336+
}
337+
338+
func updateKeyMaterial(ctx context.Context, kmsService KmsService, d *schema.ResourceData) error {
339+
param := make(map[string]interface{})
340+
param["key_id"] = d.Id()
341+
param["algorithm"] = d.Get("wrapping_algorithm").(string)
342+
param["key_spec"] = KMS_WRAPPING_KEY_SPEC_RSA_2048
343+
param["key_material_base64"] = d.Get("key_material_base64")
344+
param["valid_to"] = d.Get("valid_to").(int)
345+
346+
var err error
347+
if param["key_material_base64"] == "" {
348+
err = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
349+
e := kmsService.DeleteImportKeyMaterial(ctx, d.Id())
350+
if e != nil {
351+
return retryError(e)
352+
}
353+
return nil
354+
})
355+
} else {
356+
err = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
357+
e := kmsService.ImportKeyMaterial(ctx, param)
358+
if e != nil {
359+
return retryError(e)
360+
}
361+
return nil
362+
})
363+
}
364+
365+
return err
366+
}

0 commit comments

Comments
 (0)