-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add google_kms_secret_ciphertext resource, deprecate datasource
Signed-off-by: Modular Magician <[email protected]>
- Loading branch information
1 parent
90324a0
commit 807e8c3
Showing
8 changed files
with
383 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
// ---------------------------------------------------------------------------- | ||
// | ||
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** | ||
// | ||
// ---------------------------------------------------------------------------- | ||
// | ||
// 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 google | ||
|
||
import ( | ||
"encoding/base64" | ||
"fmt" | ||
"log" | ||
"reflect" | ||
"regexp" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
) | ||
|
||
func resourceKMSSecretCiphertext() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceKMSSecretCiphertextCreate, | ||
Read: resourceKMSSecretCiphertextRead, | ||
Delete: resourceKMSSecretCiphertextDelete, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(4 * time.Minute), | ||
Delete: schema.DefaultTimeout(4 * time.Minute), | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"crypto_key": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: `The full name of the CryptoKey that will be used to encrypt the provided plaintext. | ||
Format: ''projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/cryptoKeys/{{cryptoKey}}''`, | ||
}, | ||
"plaintext": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: `The plaintext to be encrypted.`, | ||
Sensitive: true, | ||
}, | ||
"ciphertext": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `Contains the result of encrypting the provided plaintext, encoded in base64.`, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceKMSSecretCiphertextCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
obj := make(map[string]interface{}) | ||
plaintextProp, err := expandKMSSecretCiphertextPlaintext(d.Get("plaintext"), d, config) | ||
if err != nil { | ||
return err | ||
} else if v, ok := d.GetOkExists("plaintext"); !isEmptyValue(reflect.ValueOf(plaintextProp)) && (ok || !reflect.DeepEqual(v, plaintextProp)) { | ||
obj["plaintext"] = plaintextProp | ||
} | ||
|
||
url, err := replaceVars(d, config, "{{KMSBasePath}}{{crypto_key}}:encrypt") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[DEBUG] Creating new SecretCiphertext: %#v", obj) | ||
var project string | ||
if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil { | ||
project = parts[1] | ||
} | ||
res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) | ||
if err != nil { | ||
return fmt.Errorf("Error creating SecretCiphertext: %s", err) | ||
} | ||
|
||
// Store the ID now | ||
id, err := replaceVars(d, config, "{{crypto_key}}/{{ciphertext}}") | ||
if err != nil { | ||
return fmt.Errorf("Error constructing id: %s", err) | ||
} | ||
d.SetId(id) | ||
|
||
log.Printf("[DEBUG] Finished creating SecretCiphertext %q: %#v", d.Id(), res) | ||
|
||
// we don't set anything on read and instead do it all in create | ||
ciphertext, ok := res["ciphertext"] | ||
if !ok { | ||
return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.") | ||
} | ||
d.Set("ciphertext", ciphertext.(string)) | ||
|
||
id, err = replaceVars(d, config, "{{crypto_key}}/{{ciphertext}}") | ||
if err != nil { | ||
return fmt.Errorf("Error constructing id: %s", err) | ||
} | ||
d.SetId(id) | ||
|
||
return resourceKMSSecretCiphertextRead(d, meta) | ||
} | ||
|
||
func resourceKMSSecretCiphertextRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
url, err := replaceVars(d, config, "{{KMSBasePath}}{{crypto_key}}") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var project string | ||
if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil { | ||
project = parts[1] | ||
} | ||
res, err := sendRequest(config, "GET", project, url, nil) | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("KMSSecretCiphertext %q", d.Id())) | ||
} | ||
|
||
res, err = resourceKMSSecretCiphertextDecoder(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 KMSSecretCiphertext because it no longer exists.") | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceKMSSecretCiphertextDelete(d *schema.ResourceData, meta interface{}) error { | ||
log.Printf("[WARNING] KMS SecretCiphertext resources"+ | ||
" cannot be deleted from GCP. The resource %s will be removed from Terraform"+ | ||
" state, but will still be present on the server.", d.Id()) | ||
d.SetId("") | ||
|
||
return nil | ||
} | ||
|
||
func expandKMSSecretCiphertextPlaintext(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { | ||
if v == nil { | ||
return nil, nil | ||
} | ||
|
||
return base64.StdEncoding.EncodeToString([]byte(v.(string))), nil | ||
} | ||
|
||
func resourceKMSSecretCiphertextDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) { | ||
return res, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package google | ||
|
||
import ( | ||
"encoding/base64" | ||
"fmt" | ||
"log" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/terraform" | ||
"google.golang.org/api/cloudkms/v1" | ||
) | ||
|
||
func TestAccKmsSecretCiphertext_basic(t *testing.T) { | ||
t.Parallel() | ||
|
||
kms := BootstrapKMSKey(t) | ||
|
||
plaintext := fmt.Sprintf("secret-%s", acctest.RandString(10)) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testGoogleKmsSecretCiphertext(kms.CryptoKey.Name, plaintext), | ||
Check: func(s *terraform.State) error { | ||
plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "google_kms_secret_ciphertext.acceptance") | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return resource.TestCheckResourceAttr("google_kms_secret_ciphertext.acceptance", "plaintext", plaintext)(s) | ||
}, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccDecryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyId string, secretCiphertextResourceName string) (string, error) { | ||
config := testAccProvider.Meta().(*Config) | ||
rs, ok := s.RootModule().Resources[secretCiphertextResourceName] | ||
if !ok { | ||
return "", fmt.Errorf("Resource not found: %s", secretCiphertextResourceName) | ||
} | ||
ciphertext, ok := rs.Primary.Attributes["ciphertext"] | ||
if !ok { | ||
return "", fmt.Errorf("Attribute 'ciphertext' not found in resource '%s'", secretCiphertextResourceName) | ||
} | ||
|
||
kmsDecryptRequest := &cloudkms.DecryptRequest{ | ||
Ciphertext: ciphertext, | ||
} | ||
|
||
decryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Decrypt(cryptoKeyId, kmsDecryptRequest).Do() | ||
|
||
if err != nil { | ||
return "", fmt.Errorf("Error decrypting ciphertext: %s", err) | ||
} | ||
|
||
plaintextBytes, err := base64.StdEncoding.DecodeString(decryptResponse.Plaintext) | ||
|
||
if err != nil { | ||
return "", err | ||
} | ||
|
||
plaintext := string(plaintextBytes) | ||
log.Printf("[INFO] Successfully decrypted ciphertext and got plaintext: %s", plaintext) | ||
|
||
return plaintext, nil | ||
} | ||
|
||
func testGoogleKmsSecretCiphertext(cryptoKeyTerraformId, plaintext string) string { | ||
return fmt.Sprintf(` | ||
resource "google_kms_secret_ciphertext" "acceptance" { | ||
crypto_key = "%s" | ||
plaintext = "%s" | ||
} | ||
`, cryptoKeyTerraformId, plaintext) | ||
} |
Oops, something went wrong.