Skip to content

Commit

Permalink
Add resources for Cloud Logging default settings (GoogleCloudPlatform…
Browse files Browse the repository at this point in the history
…#9409)

* Add folder and organization setting resources

* Try GetTestOrgTargetFromEnv instead of GetTestOrgFromEnv.

* Use correct organization for testing.

* Remove key rotation to fix VCR test.

* Don't specify fields matching default values.

* Specify true instead of yes.

* Use BootstrapKMSKeyInLocation instead of creating new keys.

* Add missing quotes

* Add additional examples to generate additional tests.

* Remove unneeded resources from examples.

* Simplify tests to be one full resource creation and one update.

* Fix typo in test

* Document and cleanup example.
  • Loading branch information
zachberger authored and kapreus committed Jan 2, 2024
1 parent a29fad7 commit 45f842c
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 0 deletions.
84 changes: 84 additions & 0 deletions mmv1/products/logging/FolderSettings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Copyright 2023 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Resource
name: 'FolderSettings'
description: |
Default resource settings control whether CMEK is required for new log buckets. These settings also determine the storage location for the _Default and _Required log buckets, and whether the _Default sink is enabled or disabled.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Configure default settings for organizations and folders': 'https://cloud.google.com/logging/docs/default-settings'
api: 'https://cloud.google.com/logging/docs/reference/v2/rest/v2/TopLevel/getSettings'
base_url: 'folders/{{folder}}/settings'
self_link: 'folders/{{folder}}/settings'
import_format: ['folders/{{folder}}/settings']
# Hardcode the updateMask since d.HasChanged does not work on create.
create_url: 'folders/{{folder}}/settings?updateMask=disableDefaultSink,storageLocation,kmsKeyName'
update_url: 'folders/{{folder}}/settings?updateMask=disableDefaultSink,storageLocation,kmsKeyName'
# This is a singleton resource that already is created, so create
# is really an update, and therefore should be PATCHed.
create_verb: :PATCH
update_verb: :PATCH
# update_mask: true
# This is a singleton resource that cannot be deleted, so skip delete.
skip_delete: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "logging_folder_settings_all"
primary_resource_id: "example"
vars:
key_name: "kms-key"
folder_name: "folder-name"
test_env_vars:
org_id: :ORG_ID
test_vars_overrides:
key_name: 'acctest.BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name'
parameters:
- !ruby/object:Api::Type::String
name: 'folder'
required: true
immutable: true
url_param_only: true
description: |
The folder for which to retrieve settings.
properties:
- !ruby/object:Api::Type::String
name: name
output: true
description: |
The resource name of the settings.
- !ruby/object:Api::Type::String
name: kmsKeyName
default_from_api: true
description: |
The resource name for the configured Cloud KMS key.
- !ruby/object:Api::Type::String
name: kmsServiceAccountId
output: true
description: |
The service account that will be used by the Log Router to access your Cloud KMS key.
- !ruby/object:Api::Type::String
name: storageLocation
default_from_api: true
description: |
The storage location that Cloud Logging will use to create new resources when a location is needed but not explicitly provided.
- !ruby/object:Api::Type::Boolean
name: disableDefaultSink
default_from_api: true
description: |
If set to true, the _Default sink in newly created projects and folders will created in a disabled state. This can be used to automatically disable log storage if there is already an aggregated sink configured in the hierarchy. The _Default sink can be re-enabled manually if needed.
- !ruby/object:Api::Type::String
name: loggingServiceAccountId
output: true
description: |
The service account for the given container. Sinks use this service account as their writerIdentity if no custom service account is provided.
82 changes: 82 additions & 0 deletions mmv1/products/logging/OrganizationSettings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright 2023 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Resource
name: 'OrganizationSettings'
description: |
Default resource settings control whether CMEK is required for new log buckets. These settings also determine the storage location for the _Default and _Required log buckets, and whether the _Default sink is enabled or disabled.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Configure default settings for organizations and folders': 'https://cloud.google.com/logging/docs/default-settings'
api: 'https://cloud.google.com/logging/docs/reference/v2/rest/v2/TopLevel/getSettings'
base_url: 'organizations/{{organization}}/settings'
self_link: 'organizations/{{organization}}/settings'
import_format: ['organizations/{{organization}}/settings']
# Hardcode the updateMask since d.HasChanged does not work on create.
create_url: 'organizations/{{organization}}/settings?updateMask=disableDefaultSink,storageLocation,kmsKeyName'
update_url: 'organizations/{{organization}}/settings?updateMask=disableDefaultSink,storageLocation,kmsKeyName'
# This is a singleton resource that already is created, so create
# is really an update, and therefore should be PATCHed.
create_verb: :PATCH
update_verb: :PATCH
# This is a singleton resource that cannot be deleted, so skip delete.
skip_delete: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "logging_organization_settings_all"
primary_resource_id: "example"
# Covered by update test.
skip_test: true
vars:
key_name: "kms-key"
test_env_vars:
org_id: :ORG_TARGET
parameters:
- !ruby/object:Api::Type::String
name: 'organization'
required: true
immutable: true
url_param_only: true
description: |
The organization for which to retrieve or configure settings.
properties:
- !ruby/object:Api::Type::String
name: name
output: true
description: |
The resource name of the settings.
- !ruby/object:Api::Type::String
name: kmsKeyName
default_from_api: true
description: |
The resource name for the configured Cloud KMS key.
- !ruby/object:Api::Type::String
name: kmsServiceAccountId
output: true
description: |
The service account that will be used by the Log Router to access your Cloud KMS key.
- !ruby/object:Api::Type::String
name: storageLocation
default_from_api: true
description: |
The storage location that Cloud Logging will use to create new resources when a location is needed but not explicitly provided.
- !ruby/object:Api::Type::Boolean
name: disableDefaultSink
default_from_api: true
description: |
If set to true, the _Default sink in newly created projects and folders will created in a disabled state. This can be used to automatically disable log storage if there is already an aggregated sink configured in the hierarchy. The _Default sink can be re-enabled manually if needed.
- !ruby/object:Api::Type::String
name: loggingServiceAccountId
output: true
description: |
The service account for the given container. Sinks use this service account as their writerIdentity if no custom service account is provided.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
resource "google_logging_folder_settings" "<%= ctx[:primary_resource_id] %>" {
disable_default_sink = true
folder = google_folder.my_folder.folder_id
kms_key_name = "<%= ctx[:vars]['key_name'] %>"
storage_location = "us-central1"
depends_on = [ google_kms_crypto_key_iam_member.iam ]
}

resource "google_folder" "my_folder" {
display_name = "<%= ctx[:vars]['folder_name'] %>"
parent = "organizations/<%= ctx[:test_env_vars]['org_id'] %>"
}

data "google_logging_folder_settings" "settings" {
folder = google_folder.my_folder.folder_id
}

resource "google_kms_crypto_key_iam_member" "iam" {
crypto_key_id = "<%= ctx[:vars]['key_name'] %>"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:${data.google_logging_folder_settings.settings.kms_service_account_id}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
resource "google_logging_organization_settings" "<%= ctx[:primary_resource_id] %>" {
disable_default_sink = true
kms_key_name = "<%= ctx[:vars]['key_name'] %>"
organization = "<%= ctx[:test_env_vars]['org_id'] %>"
storage_location = "us-central1"
depends_on = [ google_kms_crypto_key_iam_member.iam ]
}

data "google_logging_organization_settings" "settings" {
organization = "<%= ctx[:test_env_vars]['org_id'] %>"
}

resource "google_kms_crypto_key_iam_member" "iam" {
crypto_key_id = "<%= ctx[:vars]['key_name'] %>"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:${data.google_logging_organization_settings.settings.kms_service_account_id}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package logging_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

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

context := map[string]interface{}{
"org_id": envvar.GetTestOrgFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
"original_key": acctest.BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name,
"updated_key": acctest.BootstrapKMSKeyInLocation(t, "us-east1").CryptoKey.Name,
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccLoggingFolderSettings_onlyRequired(context),
},
{
ResourceName: "google_logging_folder_settings.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"folder"},
},
{
Config: testAccLoggingFolderSettings_full(context),
},
{
ResourceName: "google_logging_folder_settings.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"folder"},
},
},
})
}

func testAccLoggingFolderSettings_full(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_logging_folder_settings" "example" {
disable_default_sink = true
folder = google_folder.my_folder.folder_id
kms_key_name = "%{original_key}"
storage_location = "us-central1"
depends_on = [ google_kms_crypto_key_iam_member.iam ]
}
resource "google_folder" "my_folder" {
display_name = "tf-test-folder-%{random_suffix}"
parent = "organizations/%{org_id}"
}
data "google_logging_folder_settings" "settings" {
folder = google_folder.my_folder.folder_id
}
resource "google_kms_crypto_key_iam_member" "iam" {
crypto_key_id = "%{original_key}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:${data.google_logging_folder_settings.settings.kms_service_account_id}"
}
`, context)
}

func testAccLoggingFolderSettings_onlyRequired(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_logging_folder_settings" "example" {
folder = google_folder.my_folder.folder_id
}
resource "google_folder" "my_folder" {
display_name = "tf-test-folder-%{random_suffix}"
parent = "organizations/%{org_id}"
}
`, context)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package logging_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

func TestAccLoggingOrganizationSettings_update(t *testing.T) {
context := map[string]interface{}{
"org_id": envvar.GetTestOrgTargetFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
"original_key": acctest.BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name,
"updated_key": acctest.BootstrapKMSKeyInLocation(t, "us-east1").CryptoKey.Name,
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccLoggingOrganizationSettings_onlyRequired(context),
},
{
ResourceName: "google_logging_organization_settings.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"organization"},
},
{
Config: testAccLoggingOrganizationSettings_full(context),
},
{
ResourceName: "google_logging_organization_settings.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"organization"},
},
},
})
}

func testAccLoggingOrganizationSettings_full(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_logging_organization_settings" "example" {
disable_default_sink = false
kms_key_name = "%{original_key}"
organization = "%{org_id}"
storage_location = "us-central1"
depends_on = [ google_kms_crypto_key_iam_member.iam ]
}
data "google_logging_organization_settings" "settings" {
organization = "%{org_id}"
}
resource "google_kms_crypto_key_iam_member" "iam" {
crypto_key_id = "%{original_key}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:${data.google_logging_organization_settings.settings.kms_service_account_id}"
}
`, context)
}

func testAccLoggingOrganizationSettings_onlyRequired(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_logging_organization_settings" "example" {
organization = "%{org_id}"
}
`, context)
}

0 comments on commit 45f842c

Please sign in to comment.