blob: df9fb749fa61fa6cd693725fa6df0466c243b77f [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** Type: MMv1 ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------
package kms
import (
"context"
"fmt"
"log"
"net/http"
"reflect"
"regexp"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/verify"
)
func ResourceKMSCryptoKey() *schema.Resource {
return &schema.Resource{
Create: resourceKMSCryptoKeyCreate,
Read: resourceKMSCryptoKeyRead,
Update: resourceKMSCryptoKeyUpdate,
Delete: resourceKMSCryptoKeyDelete,
Importer: &schema.ResourceImporter{
State: resourceKMSCryptoKeyImport,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(20 * time.Minute),
Update: schema.DefaultTimeout(20 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceKMSCryptoKeyResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: ResourceKMSCryptoKeyUpgradeV0,
Version: 0,
},
},
CustomizeDiff: customdiff.All(
tpgresource.SetLabelsDiff,
),
Schema: map[string]*schema.Schema{
"key_ring": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: kmsCryptoKeyRingsEquivalent,
Description: `The KeyRing that this key belongs to.
Format: ''projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}''.`,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The resource name for the CryptoKey.`,
},
"crypto_key_backend": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
Description: `The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey.
The resource name is in the format "projects/*/locations/*/ekmConnections/*" and only applies to "EXTERNAL_VPC" keys.`,
},
"destroy_scheduled_duration": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
Description: `The period of time that versions of this key spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED.
If not specified at creation time, the default duration is 30 days.`,
},
"import_only": {
Type: schema.TypeBool,
Computed: true,
Optional: true,
ForceNew: true,
Description: `Whether this key may contain imported versions only.`,
},
"key_access_justifications_policy": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `The policy used for Key Access Justifications Policy Enforcement. If this
field is present and this key is enrolled in Key Access Justifications
Policy Enforcement, the policy will be evaluated in encrypt, decrypt, and
sign operations, and the operation will fail if rejected by the policy. The
policy is defined by specifying zero or more allowed justification codes.
https://cloud.google.com/assured-workloads/key-access-justifications/docs/justification-codes
By default, this field is absent, and all justification codes are allowed.
This field is currently in beta and is subject to change.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"allowed_access_reasons": {
Type: schema.TypeList,
Optional: true,
Description: `The list of allowed reasons for access to this CryptoKey. Zero allowed
access reasons means all encrypt, decrypt, and sign operations for
this CryptoKey will fail.`,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
"labels": {
Type: schema.TypeMap,
Optional: true,
Description: `Labels with user-defined metadata to apply to this resource.
**Note**: This field is non-authoritative, and will only manage the labels present in your configuration.
Please refer to the field 'effective_labels' for all of the labels present on the resource.`,
Elem: &schema.Schema{Type: schema.TypeString},
},
"purpose": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `The immutable purpose of this CryptoKey. See the
[purpose reference](https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose)
for possible inputs.
Default value is "ENCRYPT_DECRYPT".`,
Default: "ENCRYPT_DECRYPT",
},
"rotation_period": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.OrEmpty(validateKmsCryptoKeyRotationPeriod),
Description: `Every time this period passes, generate a new CryptoKeyVersion and set it as the primary.
The first rotation will take place after the specified period. The rotation period has
the format of a decimal number with up to 9 fractional digits, followed by the
letter 's' (seconds). It must be greater than a day (ie, 86400).`,
},
"skip_initial_version_creation": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Description: `If set to true, the request will create a CryptoKey without any CryptoKeyVersions.
You must use the 'google_kms_crypto_key_version' resource to create a new CryptoKeyVersion
or 'google_kms_key_ring_import_job' resource to import the CryptoKeyVersion.`,
},
"version_template": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `A template describing settings for new crypto key versions.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"algorithm": {
Type: schema.TypeString,
Required: true,
Description: `The algorithm to use when creating a version based on this template.
See the [algorithm reference](https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm) for possible inputs.`,
},
"protection_level": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `The protection level to use when creating a version based on this template. Possible values include "SOFTWARE", "HSM", "EXTERNAL", "EXTERNAL_VPC". Defaults to "SOFTWARE".`,
Default: "SOFTWARE",
},
},
},
},
"effective_labels": {
Type: schema.TypeMap,
Computed: true,
Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`,
Elem: &schema.Schema{Type: schema.TypeString},
},
"primary": {
Type: schema.TypeList,
Computed: true,
Description: `A copy of the primary CryptoKeyVersion that will be used by cryptoKeys.encrypt when this CryptoKey is given in EncryptRequest.name.
Keys with purpose ENCRYPT_DECRYPT may have a primary. For other keys, this field will be unset.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
Description: `The resource name for this CryptoKeyVersion.`,
},
"state": {
Type: schema.TypeString,
Computed: true,
Description: `The current state of the CryptoKeyVersion.`,
},
},
},
},
"terraform_labels": {
Type: schema.TypeMap,
Computed: true,
Description: `The combination of labels configured directly on the resource
and default labels configured on the provider.`,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
UseJSONNumber: true,
}
}
func resourceKMSCryptoKeyCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
obj := make(map[string]interface{})
purposeProp, err := expandKMSCryptoKeyPurpose(d.Get("purpose"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("purpose"); !tpgresource.IsEmptyValue(reflect.ValueOf(purposeProp)) && (ok || !reflect.DeepEqual(v, purposeProp)) {
obj["purpose"] = purposeProp
}
rotationPeriodProp, err := expandKMSCryptoKeyRotationPeriod(d.Get("rotation_period"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("rotation_period"); !tpgresource.IsEmptyValue(reflect.ValueOf(rotationPeriodProp)) && (ok || !reflect.DeepEqual(v, rotationPeriodProp)) {
obj["rotationPeriod"] = rotationPeriodProp
}
versionTemplateProp, err := expandKMSCryptoKeyVersionTemplate(d.Get("version_template"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("version_template"); !tpgresource.IsEmptyValue(reflect.ValueOf(versionTemplateProp)) && (ok || !reflect.DeepEqual(v, versionTemplateProp)) {
obj["versionTemplate"] = versionTemplateProp
}
destroyScheduledDurationProp, err := expandKMSCryptoKeyDestroyScheduledDuration(d.Get("destroy_scheduled_duration"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("destroy_scheduled_duration"); !tpgresource.IsEmptyValue(reflect.ValueOf(destroyScheduledDurationProp)) && (ok || !reflect.DeepEqual(v, destroyScheduledDurationProp)) {
obj["destroyScheduledDuration"] = destroyScheduledDurationProp
}
importOnlyProp, err := expandKMSCryptoKeyImportOnly(d.Get("import_only"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("import_only"); !tpgresource.IsEmptyValue(reflect.ValueOf(importOnlyProp)) && (ok || !reflect.DeepEqual(v, importOnlyProp)) {
obj["importOnly"] = importOnlyProp
}
cryptoKeyBackendProp, err := expandKMSCryptoKeyCryptoKeyBackend(d.Get("crypto_key_backend"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("crypto_key_backend"); !tpgresource.IsEmptyValue(reflect.ValueOf(cryptoKeyBackendProp)) && (ok || !reflect.DeepEqual(v, cryptoKeyBackendProp)) {
obj["cryptoKeyBackend"] = cryptoKeyBackendProp
}
keyAccessJustificationsPolicyProp, err := expandKMSCryptoKeyKeyAccessJustificationsPolicy(d.Get("key_access_justifications_policy"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("key_access_justifications_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(keyAccessJustificationsPolicyProp)) && (ok || !reflect.DeepEqual(v, keyAccessJustificationsPolicyProp)) {
obj["keyAccessJustificationsPolicy"] = keyAccessJustificationsPolicyProp
}
labelsProp, err := expandKMSCryptoKeyEffectiveLabels(d.Get("effective_labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
obj, err = resourceKMSCryptoKeyEncoder(d, meta, obj)
if err != nil {
return err
}
url, err := tpgresource.ReplaceVars(d, config, "{{KMSBasePath}}{{key_ring}}/cryptoKeys?cryptoKeyId={{name}}&skipInitialVersionCreation={{skip_initial_version_creation}}")
if err != nil {
return err
}
log.Printf("[DEBUG] Creating new CryptoKey: %#v", obj)
billingProject := ""
if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil {
billingProject = parts[1]
}
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
headers := make(http.Header)
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "POST",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutCreate),
Headers: headers,
})
if err != nil {
return fmt.Errorf("Error creating CryptoKey: %s", err)
}
// Store the ID now
id, err := tpgresource.ReplaceVars(d, config, "{{key_ring}}/cryptoKeys/{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
log.Printf("[DEBUG] Finished creating CryptoKey %q: %#v", d.Id(), res)
return resourceKMSCryptoKeyRead(d, meta)
}
func resourceKMSCryptoKeyRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
url, err := tpgresource.ReplaceVars(d, config, "{{KMSBasePath}}{{key_ring}}/cryptoKeys/{{name}}")
if err != nil {
return err
}
billingProject := ""
if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil {
billingProject = parts[1]
}
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
headers := make(http.Header)
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Headers: headers,
})
if err != nil {
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("KMSCryptoKey %q", d.Id()))
}
res, err = resourceKMSCryptoKeyDecoder(d, meta, res)
if err != nil {
return err
}
if res == nil {
// Decoding the object has resulted in it being gone. It may be marked deleted
log.Printf("[DEBUG] Removing KMSCryptoKey because it no longer exists.")
d.SetId("")
return nil
}
if err := d.Set("labels", flattenKMSCryptoKeyLabels(res["labels"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("primary", flattenKMSCryptoKeyPrimary(res["primary"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("purpose", flattenKMSCryptoKeyPurpose(res["purpose"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("rotation_period", flattenKMSCryptoKeyRotationPeriod(res["rotationPeriod"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("version_template", flattenKMSCryptoKeyVersionTemplate(res["versionTemplate"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("destroy_scheduled_duration", flattenKMSCryptoKeyDestroyScheduledDuration(res["destroyScheduledDuration"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("import_only", flattenKMSCryptoKeyImportOnly(res["importOnly"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("crypto_key_backend", flattenKMSCryptoKeyCryptoKeyBackend(res["cryptoKeyBackend"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("key_access_justifications_policy", flattenKMSCryptoKeyKeyAccessJustificationsPolicy(res["keyAccessJustificationsPolicy"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("terraform_labels", flattenKMSCryptoKeyTerraformLabels(res["labels"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
if err := d.Set("effective_labels", flattenKMSCryptoKeyEffectiveLabels(res["labels"], d, config)); err != nil {
return fmt.Errorf("Error reading CryptoKey: %s", err)
}
return nil
}
func resourceKMSCryptoKeyUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
billingProject := ""
obj := make(map[string]interface{})
rotationPeriodProp, err := expandKMSCryptoKeyRotationPeriod(d.Get("rotation_period"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("rotation_period"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, rotationPeriodProp)) {
obj["rotationPeriod"] = rotationPeriodProp
}
versionTemplateProp, err := expandKMSCryptoKeyVersionTemplate(d.Get("version_template"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("version_template"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, versionTemplateProp)) {
obj["versionTemplate"] = versionTemplateProp
}
keyAccessJustificationsPolicyProp, err := expandKMSCryptoKeyKeyAccessJustificationsPolicy(d.Get("key_access_justifications_policy"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("key_access_justifications_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, keyAccessJustificationsPolicyProp)) {
obj["keyAccessJustificationsPolicy"] = keyAccessJustificationsPolicyProp
}
labelsProp, err := expandKMSCryptoKeyEffectiveLabels(d.Get("effective_labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}
obj, err = resourceKMSCryptoKeyUpdateEncoder(d, meta, obj)
if err != nil {
return err
}
url, err := tpgresource.ReplaceVars(d, config, "{{KMSBasePath}}{{key_ring}}/cryptoKeys/{{name}}")
if err != nil {
return err
}
log.Printf("[DEBUG] Updating CryptoKey %q: %#v", d.Id(), obj)
headers := make(http.Header)
updateMask := []string{}
if d.HasChange("rotation_period") {
updateMask = append(updateMask, "rotationPeriod",
"nextRotationTime")
}
if d.HasChange("version_template") {
updateMask = append(updateMask, "versionTemplate.algorithm")
}
if d.HasChange("key_access_justifications_policy") {
updateMask = append(updateMask, "keyAccessJustificationsPolicy")
}
if d.HasChange("effective_labels") {
updateMask = append(updateMask, "labels")
}
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}
if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil {
billingProject = parts[1]
}
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
// if updateMask is empty we are not updating anything so skip the post
if len(updateMask) > 0 {
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "PATCH",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutUpdate),
Headers: headers,
})
if err != nil {
return fmt.Errorf("Error updating CryptoKey %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished updating CryptoKey %q: %#v", d.Id(), res)
}
}
return resourceKMSCryptoKeyRead(d, meta)
}
func resourceKMSCryptoKeyDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
cryptoKeyId, err := ParseKmsCryptoKeyId(d.Id(), config)
if err != nil {
return err
}
log.Printf(`
[WARNING] KMS CryptoKey resources cannot be deleted from GCP. The CryptoKey %s will be removed from Terraform state,
and all its CryptoKeyVersions will be destroyed, but it will still be present in the project.`, cryptoKeyId.CryptoKeyId())
// Delete all versions of the key
if err := clearCryptoKeyVersions(cryptoKeyId, userAgent, config); err != nil {
return err
}
// Make sure automatic key rotation is disabled if set
if d.Get("rotation_period") != "" {
if err := disableCryptoKeyRotation(cryptoKeyId, userAgent, config); err != nil {
return fmt.Errorf(
"While cryptoKeyVersions were cleared, Terraform was unable to disable automatic rotation of key due to an error: %s."+
"Please retry or manually disable automatic rotation to prevent creation of a new version of this key.", err)
}
}
d.SetId("")
return nil
}
func resourceKMSCryptoKeyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*transport_tpg.Config)
cryptoKeyId, err := ParseKmsCryptoKeyId(d.Id(), config)
if err != nil {
return nil, err
}
if err := d.Set("key_ring", cryptoKeyId.KeyRingId.KeyRingId()); err != nil {
return nil, fmt.Errorf("Error setting key_ring: %s", err)
}
if err := d.Set("name", cryptoKeyId.Name); err != nil {
return nil, fmt.Errorf("Error setting name: %s", err)
}
if err := d.Set("skip_initial_version_creation", false); err != nil {
return nil, fmt.Errorf("Error setting skip_initial_version_creation: %s", err)
}
id, err := tpgresource.ReplaceVars(d, config, "{{key_ring}}/cryptoKeys/{{name}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
return []*schema.ResourceData{d}, nil
}
func flattenKMSCryptoKeyLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
}
transformed := make(map[string]interface{})
if l, ok := d.GetOkExists("labels"); ok {
for k := range l.(map[string]interface{}) {
transformed[k] = v.(map[string]interface{})[k]
}
}
return transformed
}
func flattenKMSCryptoKeyPrimary(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["name"] =
flattenKMSCryptoKeyPrimaryName(original["name"], d, config)
transformed["state"] =
flattenKMSCryptoKeyPrimaryState(original["state"], d, config)
return []interface{}{transformed}
}
func flattenKMSCryptoKeyPrimaryName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyPrimaryState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyPurpose(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyRotationPeriod(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyVersionTemplate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["algorithm"] =
flattenKMSCryptoKeyVersionTemplateAlgorithm(original["algorithm"], d, config)
transformed["protection_level"] =
flattenKMSCryptoKeyVersionTemplateProtectionLevel(original["protectionLevel"], d, config)
return []interface{}{transformed}
}
func flattenKMSCryptoKeyVersionTemplateAlgorithm(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyVersionTemplateProtectionLevel(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyDestroyScheduledDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyImportOnly(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyCryptoKeyBackend(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyKeyAccessJustificationsPolicy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["allowed_access_reasons"] =
flattenKMSCryptoKeyKeyAccessJustificationsPolicyAllowedAccessReasons(original["allowedAccessReasons"], d, config)
return []interface{}{transformed}
}
func flattenKMSCryptoKeyKeyAccessJustificationsPolicyAllowedAccessReasons(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenKMSCryptoKeyTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
}
transformed := make(map[string]interface{})
if l, ok := d.GetOkExists("terraform_labels"); ok {
for k := range l.(map[string]interface{}) {
transformed[k] = v.(map[string]interface{})[k]
}
}
return transformed
}
func flattenKMSCryptoKeyEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func expandKMSCryptoKeyPurpose(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyRotationPeriod(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyVersionTemplate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})
transformedAlgorithm, err := expandKMSCryptoKeyVersionTemplateAlgorithm(original["algorithm"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAlgorithm); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["algorithm"] = transformedAlgorithm
}
transformedProtectionLevel, err := expandKMSCryptoKeyVersionTemplateProtectionLevel(original["protection_level"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedProtectionLevel); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["protectionLevel"] = transformedProtectionLevel
}
return transformed, nil
}
func expandKMSCryptoKeyVersionTemplateAlgorithm(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyVersionTemplateProtectionLevel(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyDestroyScheduledDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyImportOnly(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyCryptoKeyBackend(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyKeyAccessJustificationsPolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})
transformedAllowedAccessReasons, err := expandKMSCryptoKeyKeyAccessJustificationsPolicyAllowedAccessReasons(original["allowed_access_reasons"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAllowedAccessReasons); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["allowedAccessReasons"] = transformedAllowedAccessReasons
}
return transformed, nil
}
func expandKMSCryptoKeyKeyAccessJustificationsPolicyAllowedAccessReasons(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandKMSCryptoKeyEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
}
m := make(map[string]string)
for k, val := range v.(map[string]interface{}) {
m[k] = val.(string)
}
return m, nil
}
func resourceKMSCryptoKeyEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
// if rotationPeriod is set, nextRotationTime must also be set.
if d.Get("rotation_period") != "" {
rotationPeriod := d.Get("rotation_period").(string)
nextRotation, err := kmsCryptoKeyNextRotation(time.Now(), rotationPeriod)
if err != nil {
return nil, fmt.Errorf("Error setting CryptoKey rotation period: %s", err.Error())
}
obj["nextRotationTime"] = nextRotation
}
// set to false if it is not true explicitly
if !(d.Get("skip_initial_version_creation").(bool)) {
if err := d.Set("skip_initial_version_creation", false); err != nil {
return nil, fmt.Errorf("Error setting skip_initial_version_creation: %s", err)
}
}
return obj, nil
}
func resourceKMSCryptoKeyUpdateEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
// if rotationPeriod is changed, nextRotationTime must also be set.
if d.HasChange("rotation_period") && d.Get("rotation_period") != "" {
rotationPeriod := d.Get("rotation_period").(string)
nextRotation, err := kmsCryptoKeyNextRotation(time.Now(), rotationPeriod)
if err != nil {
return nil, fmt.Errorf("Error setting CryptoKey rotation period: %s", err.Error())
}
obj["nextRotationTime"] = nextRotation
}
return obj, nil
}
func resourceKMSCryptoKeyDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
// Modify the name to be the user specified form.
// We can't just ignore_read on `name` as the linter will
// complain that the returned `res` is never used afterwards.
// Some field needs to be actually set, and we chose `name`.
res["name"] = d.Get("name").(string)
return res, nil
}
func resourceKMSCryptoKeyResourceV0() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"key_ring": {
Type: schema.TypeString,
Required: true,
},
"rotation_period": {
Type: schema.TypeString,
Optional: true,
},
"version_template": {
Type: schema.TypeList,
Optional: true,
},
"self_link": {
Type: schema.TypeString,
},
},
}
}
func ResourceKMSCryptoKeyUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
log.Printf("[DEBUG] Attributes before migration: %#v", rawState)
config := meta.(*transport_tpg.Config)
keyRingId := rawState["key_ring"].(string)
parsed, err := parseKmsKeyRingId(keyRingId, config)
if err != nil {
return nil, err
}
rawState["key_ring"] = parsed.KeyRingId()
log.Printf("[DEBUG] Attributes after migration: %#v", rawState)
return rawState, nil
}