Skip to content

Commit

Permalink
Add new Resource Cryptokeyversions (#6553) (#12926)
Browse files Browse the repository at this point in the history
* Add new resource cryptokeyVersion, and the tests.

* Resource cryptoKeyVersion -- Fix errors that prevent creation

* CryptoKeyVersion resource -- [WIP] commit

* CryptoKeyVersions -- Fix tests for create and create with skip_initial_version

* CryptoKeyVersions -- Fix after running gofmt

* CryptoKeyVersions -- modification based on PR feedback, except add update test

* CryptoKeyVersion -- Add update test

* gofmt fix the test file

* Remove unused fields and update tests

* Add custom import, yet tests aren't fully passing because of custom_delete

* Attempt to fix custom import and delete

* Delete kms_crypto_key_version.erb

* Fix Custom delete issues

* Enable importStateVerify to all tests

* Fix make lint problem

* Delete go.mod

* (1) Remove enum values for output fields
(2) fix indentation problems
(3) Fix state verify for crypto_Key
(4) Add remove test for cryptoKeyVersions
(5) WIP Fix custom_delete issues

* (1) Call destroy at cryptoKeyVersion deletion
(2) Do not destroy cryptoKeyVersion when deleting crypto_key

* CryptoKeyVersions Delete, put error handler first

* Uncomment clearCryptoKeyVersions when deleting cryptoKey

* Align with master branch, check for state before deleting cryptokeyversion

* Remove state check in cryptoKeyVersions deletion

Signed-off-by: Modular Magician <magic-modules@google.com>

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed Nov 1, 2022
1 parent a923a41 commit e394fdd
Show file tree
Hide file tree
Showing 6 changed files with 915 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .changelog/6553.txt
@@ -0,0 +1,4 @@
```release-note:new-resource
kms: Add new resource CryptoKeyVersions

```
47 changes: 47 additions & 0 deletions google/kms_utils.go
Expand Up @@ -85,6 +85,19 @@ func (s *kmsCryptoKeyId) terraformId() string {
return fmt.Sprintf("%s/%s", s.KeyRingId.terraformId(), s.Name)
}

type kmsCryptoKeyVersionId struct {
CryptoKeyId kmsCryptoKeyId
Name string
}

func (s *kmsCryptoKeyVersionId) cryptoKeyVersionId() string {
return fmt.Sprintf(s.Name)
}

func (s *kmsCryptoKeyVersionId) terraformId() string {
return fmt.Sprintf("%s/%s", s.CryptoKeyId.terraformId(), s.Name)
}

func validateKmsCryptoKeyRotationPeriod(value interface{}, _ string) (ws []string, errors []error) {
period := value.(string)
pattern := regexp.MustCompile(`^([0-9.]*\d)s$`)
Expand Down Expand Up @@ -171,8 +184,27 @@ func parseKmsCryptoKeyId(id string, config *Config) (*kmsCryptoKeyId, error) {
Name: parts[4],
}, nil
}

return nil, fmt.Errorf("Invalid CryptoKey id format, expecting `{projectId}/{locationId}/{KeyringName}/{cryptoKeyName}` or `{locationId}/{keyRingName}/{cryptoKeyName}, got id: %s`", id)
}
func parseKmsCryptoKeyVersionId(id string, config *Config) (*kmsCryptoKeyVersionId, error) {
cryptoKeyVersionRelativeLinkRegex := regexp.MustCompile("^projects/(" + ProjectRegex + ")/locations/([a-z0-9-]+)/keyRings/([a-zA-Z0-9_-]{1,63})/cryptoKeys/([a-zA-Z0-9_-]{1,63})/cryptoKeyVersions/([a-zA-Z0-9_-]{1,63})$")

if parts := cryptoKeyVersionRelativeLinkRegex.FindStringSubmatch(id); parts != nil {
return &kmsCryptoKeyVersionId{
CryptoKeyId: kmsCryptoKeyId{
KeyRingId: kmsKeyRingId{
Project: parts[1],
Location: parts[2],
Name: parts[3],
},
Name: parts[4],
},
Name: "projects/" + parts[1] + "/locations/" + parts[2] + "/keyRings/" + parts[3] + "/cryptoKeys/" + parts[4] + "/cryptoKeyVersions/" + parts[5],
}, nil
}
return nil, fmt.Errorf("Invalid CryptoKeyVersion id format, expecting `{projectId}/{locationId}/{KeyringName}/{cryptoKeyName}/{cryptoKeyVersion}` or `{locationId}/{keyRingName}/{cryptoKeyName}/{cryptoKeyVersion}, got id: %s`", id)
}

func clearCryptoKeyVersions(cryptoKeyId *kmsCryptoKeyId, userAgent string, config *Config) error {
versionsClient := config.NewKmsClient(userAgent).Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions
Expand Down Expand Up @@ -206,6 +238,21 @@ func clearCryptoKeyVersions(cryptoKeyId *kmsCryptoKeyId, userAgent string, confi
return nil
}

func deleteCryptoKeyVersions(cryptoKeyVersionId *kmsCryptoKeyVersionId, d *schema.ResourceData, userAgent string, config *Config) error {
versionsClient := config.NewKmsClient(userAgent).Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions
request := &cloudkms.DestroyCryptoKeyVersionRequest{}
destroyCall := versionsClient.Destroy(cryptoKeyVersionId.Name, request)
if config.UserProjectOverride {
destroyCall.Header().Set("X-Goog-User-Project", cryptoKeyVersionId.CryptoKeyId.KeyRingId.Project)
}
_, err := destroyCall.Do()
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ID %s", cryptoKeyVersionId.Name))
}

return nil
}

func disableCryptoKeyRotation(cryptoKeyId *kmsCryptoKeyId, userAgent string, config *Config) error {
keyClient := config.NewKmsClient(userAgent).Projects.Locations.KeyRings.CryptoKeys
patchCall := keyClient.Patch(cryptoKeyId.cryptoKeyId(), &cloudkms.CryptoKey{
Expand Down
5 changes: 3 additions & 2 deletions google/provider.go
Expand Up @@ -910,9 +910,9 @@ func Provider() *schema.Provider {
return provider
}

// Generated resources: 243
// Generated resources: 244
// Generated IAM resources: 150
// Total generated resources: 393
// Total generated resources: 394
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -1205,6 +1205,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_identity_platform_tenant": resourceIdentityPlatformTenant(),
"google_kms_key_ring": resourceKMSKeyRing(),
"google_kms_crypto_key": resourceKMSCryptoKey(),
"google_kms_crypto_key_version": resourceKMSCryptoKeyVersion(),
"google_kms_key_ring_import_job": resourceKMSKeyRingImportJob(),
"google_kms_secret_ciphertext": resourceKMSSecretCiphertext(),
"google_logging_metric": resourceLoggingMetric(),
Expand Down
264 changes: 264 additions & 0 deletions google/resource_kms_crypto_key_test.go
Expand Up @@ -440,6 +440,96 @@ func testAccCheckGoogleKmsCryptoKeyRotationDisabled(t *testing.T, projectId, loc
}
}

func TestAccKmsCryptoKeyVersion_basic(t *testing.T) {
t.Parallel()

projectId := fmt.Sprintf("tf-test-%d", randInt(t))
projectOrg := getTestOrgFromEnv(t)
projectBillingAccount := getTestBillingAccountFromEnv(t)
keyRingName := fmt.Sprintf("tf-test-%s", randString(t, 10))
cryptoKeyName := fmt.Sprintf("tf-test-%s", randString(t, 10))

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testGoogleKmsCryptoKeyVersion_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName),
},
{
ResourceName: "google_kms_crypto_key_version.crypto_key_version",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testGoogleKmsCryptoKeyVersion_removed(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName),
},
},
})
}

func TestAccKmsCryptoKeyVersion_skipInitialVersion(t *testing.T) {
t.Parallel()

projectId := fmt.Sprintf("tf-test-%d", randInt(t))
projectOrg := getTestOrgFromEnv(t)
projectBillingAccount := getTestBillingAccountFromEnv(t)
keyRingName := fmt.Sprintf("tf-test-%s", randString(t, 10))
cryptoKeyName := fmt.Sprintf("tf-test-%s", randString(t, 10))

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testGoogleKmsCryptoKeyVersion_skipInitialVersion(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName),
},
{
ResourceName: "google_kms_crypto_key_version.crypto_key_version",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccKmsCryptoKeyVersion_patch(t *testing.T) {
t.Parallel()

projectId := fmt.Sprintf("tf-test-%d", randInt(t))
projectOrg := getTestOrgFromEnv(t)
projectBillingAccount := getTestBillingAccountFromEnv(t)
keyRingName := fmt.Sprintf("tf-test-%s", randString(t, 10))
cryptoKeyName := fmt.Sprintf("tf-test-%s", randString(t, 10))
state := "DISABLED"

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testGoogleKmsCryptoKeyVersion_patchInitialize(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName),
},
{
ResourceName: "google_kms_crypto_key_version.crypto_key_version",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testGoogleKmsCryptoKeyVersion_patch("true", projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, state),
},
{
ResourceName: "google_kms_crypto_key_version.crypto_key_version",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testGoogleKmsCryptoKeyVersion_patch("false", projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, state),
},
},
})
}

// This test runs in its own project, otherwise the test project would start to get filled
// with undeletable resources
func testGoogleKmsCryptoKey_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string {
Expand Down Expand Up @@ -643,3 +733,177 @@ resource "google_kms_crypto_key" "crypto_key" {
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName)
}

func testGoogleKmsCryptoKeyVersion_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_service" "acceptance" {
project = google_project.acceptance.project_id
service = "cloudkms.googleapis.com"
}
resource "google_kms_key_ring" "key_ring" {
project = google_project_service.acceptance.project
name = "%s"
location = "us-central1"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = google_kms_key_ring.key_ring.id
labels = {
key = "value"
}
}
resource "google_kms_crypto_key_version" "crypto_key_version" {
crypto_key = google_kms_crypto_key.crypto_key.id
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName)
}

func testGoogleKmsCryptoKeyVersion_removed(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_service" "acceptance" {
project = google_project.acceptance.project_id
service = "cloudkms.googleapis.com"
}
resource "google_kms_key_ring" "key_ring" {
project = google_project_service.acceptance.project
name = "%s"
location = "us-central1"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = google_kms_key_ring.key_ring.id
labels = {
key = "value"
}
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName)
}

func testGoogleKmsCryptoKeyVersion_skipInitialVersion(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_service" "acceptance" {
project = google_project.acceptance.project_id
service = "cloudkms.googleapis.com"
}
resource "google_kms_key_ring" "key_ring" {
project = google_project_service.acceptance.project
name = "%s"
location = "us-central1"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = google_kms_key_ring.key_ring.id
labels = {
key = "value"
}
skip_initial_version_creation = true
}
resource "google_kms_crypto_key_version" "crypto_key_version" {
crypto_key = google_kms_crypto_key.crypto_key.id
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName)
}
func testGoogleKmsCryptoKeyVersion_patchInitialize(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_service" "acceptance" {
project = google_project.acceptance.project_id
service = "cloudkms.googleapis.com"
}
resource "google_kms_key_ring" "key_ring" {
project = google_project_service.acceptance.project
name = "%s"
location = "us-central1"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = google_kms_key_ring.key_ring.id
labels = {
key = "value"
}
}
resource "google_kms_crypto_key_version" "crypto_key_version" {
crypto_key = google_kms_crypto_key.crypto_key.id
lifecycle {
prevent_destroy = true
}
state = "ENABLED"
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName)
}

func testGoogleKmsCryptoKeyVersion_patch(preventDestroy, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, state string) string {
return fmt.Sprintf(`
resource "google_project" "acceptance" {
name = "%s"
project_id = "%s"
org_id = "%s"
billing_account = "%s"
}
resource "google_project_service" "acceptance" {
project = google_project.acceptance.project_id
service = "cloudkms.googleapis.com"
}
resource "google_kms_key_ring" "key_ring" {
project = google_project_service.acceptance.project
name = "%s"
location = "us-central1"
}
resource "google_kms_crypto_key" "crypto_key" {
name = "%s"
key_ring = google_kms_key_ring.key_ring.id
labels = {
key = "value"
}
}
resource "google_kms_crypto_key_version" "crypto_key_version" {
crypto_key = google_kms_crypto_key.crypto_key.id
lifecycle {
prevent_destroy = %s
}
state = "%s"
}
`, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, preventDestroy, state)
}

0 comments on commit e394fdd

Please sign in to comment.