Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added CloudQuotas service and Create QuotaPreference Resource #10019

Merged
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ff823eb
setup resoruce config and add create tests
lola98 Feb 14, 2024
c2b87a2
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Feb 14, 2024
6f37c02
add create and update test
lola98 Feb 20, 2024
bdd0e8f
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Feb 20, 2024
cf64d28
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Feb 20, 2024
17f5c74
fix lint error
lola98 Feb 20, 2024
9a62c89
fix lint error
lola98 Feb 21, 2024
13db912
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Feb 26, 2024
2c57c14
update yaml config
lola98 Feb 27, 2024
2fb6fe0
remove trailing spaces
lola98 Feb 27, 2024
9689ded
modify update test
lola98 Mar 4, 2024
28edefa
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Mar 4, 2024
d8470a9
update acceptance test and cleanup
lola98 Mar 6, 2024
95ec899
add upsert scenario for testing
lola98 Mar 7, 2024
6f3e3c7
update acceptance test syntax
lola98 Mar 7, 2024
13d04ae
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Mar 8, 2024
c1ac0f2
remove allow-missing flag & fix update test failure
lola98 Mar 11, 2024
4e70fd0
add import and id format
lola98 Mar 11, 2024
dfc19bc
teamcity test failure - manually add cloudquotas service
lola98 Mar 12, 2024
5b9add6
teamcity test failure - manually add cloudquotas service for beta
lola98 Mar 12, 2024
815126c
Merge branch 'main' into create-quota-preference-resource
lola98 Mar 13, 2024
165bdc8
add field 'validate_only' to tests
lola98 Mar 13, 2024
cd370df
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Mar 14, 2024
9171ac4
address comments & fix test failure
lola98 Mar 14, 2024
06f26de
remove unused import
lola98 Mar 15, 2024
1188bed
remove `validate_only` field, add ignore read feature to `annotations…
lola98 Mar 18, 2024
a011c53
add input only fields to ImportStateVerifyIgnore
lola98 Mar 19, 2024
760d601
update field name
lola98 Mar 19, 2024
39f787d
Merge branch 'GoogleCloudPlatform:main' into create-quota-preference-…
lola98 Mar 20, 2024
82b9241
VCR test failure: remove batch service creation
lola98 Mar 20, 2024
4ba069b
fix formatting
lola98 Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions mmv1/products/cloudquotas/QuotaPreference.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Copyright 2024 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: 'QuotaPreference'
description: |
QuotaPreference represents the preferred quota configuration specified for a project, folder or organization. There is only one QuotaPreference resource for a quota value targeting a unique set of dimensions.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Cloud Quotas Overview': 'https://cloud.google.com/docs/quotas/overview'
api: 'https://cloud.google.com/docs/quotas/reference/rest/v1/projects.locations.quotaPreferences'
base_url: '{{parent}}/locations/global/quotaPreferences'
self_link: '{{parent}}/locations/global/quotaPreferences/{{name}}'
create_url: '{{parent}}/locations/global/quotaPreferences?quotaPreferenceId={{name}}&ignoreSafetyChecks={{ignore_safety_checks}}'
update_url: '{{parent}}/locations/global/quotaPreferences/{{name}}?ignoreSafetyChecks={{ignore_safety_checks}}'
update_verb: :PATCH
update_mask: true
skip_delete: true
autogen_async: false
import_format: ['{{%parent}}/locations/global/quotaPreferences/{{name}}']
id_format: '{{parent}}/locations/global/quotaPreferences/{{name}}'

examples:
- !ruby/object:Provider::Terraform::Examples
name: "cloudquotas_quota_preference_basic"
primary_resource_id: "preference"
skip_test: true
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
vars:
name: "compute_googleapis_com-CPUS-per-project_us-east1"
test_env_vars:
project: :PROJECT_NAME

parameters:
- !ruby/object:Api::Type::String
name: 'parent'
immutable: true
url_param_only: true
required: true
default_from_api: true
description: The parent of the quota preference. Allowed parents are "projects/[project-id / number]" or "folders/[folder-id / number]" or "organizations/[org-id / number]".
- !ruby/object:Api::Type::Enum
name: 'ignore_safety_checks'
url_param_only: true
default_value: :QUOTA_SAFETY_CHECK_UNSPECIFIED
description: The list of quota safety checks to be ignored.
values:
- :QUOTA_SAFETY_CHECK_UNSPECIFIED
- :QUOTA_DECREASE_BELOW_USAGE
- :QUOTA_DECREASE_PERCENTAGE_TOO_HIGH

properties:
- !ruby/object:Api::Type::String
name: 'name'
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
default_from_api: true
pattern: '{{parent}}/locations/global/quotaPreferences/{{name}}'
description: |
The resource name of the quota preference. Required except in the CREATE requests.
diff_suppress_func: 'tpgresource.CompareSelfLinkOrResourceName'
custom_expand: templates/terraform/custom_expand/resource_from_self_link.go.erb
custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
- !ruby/object:Api::Type::String
name: 'service'
required: true
default_from_api: true
description: The name of the service to which the quota preference is applied.
- !ruby/object:Api::Type::String
name: 'quotaId'
required: true
default_from_api: true
description: |
The id of the quota to which the quota preference is applied. A quota id is unique in the service.
Example: `CPUS-per-project-region`.
- !ruby/object:Api::Type::NestedObject
name: 'quotaConfig'
required: true
description: The preferred quota configuration.
properties:
- !ruby/object:Api::Type::String
name: 'preferredValue'
required: true
description: |
The preferred value. Must be greater than or equal to -1. If set to -1, it means the value is "unlimited".
- !ruby/object:Api::Type::String
name: 'stateDetail'
output: true
description: Optional details about the state of this quota preference.
- !ruby/object:Api::Type::String
name: 'grantedValue'
output: true
description: Granted quota value.
- !ruby/object:Api::Type::String
name: 'traceId'
output: true
description: |
The trace id that the Google Cloud uses to provision the requested quota. This trace id may be used by the client to contact Cloud support to track the state of a quota preference request. The trace id is only produced for increase requests and is unique for each request. The quota decrease requests do not have a trace id.
- !ruby/object:Api::Type::KeyValuePairs
name: 'annotations'
custom_flatten: 'templates/terraform/custom_flatten/cloudquotas_quota_preference_annotations.go.erb'
description: |-
The annotations map for clients to store small amounts of arbitrary data. Do not put PII or other sensitive information here. See https://google.aip.dev/128#annotations.

An object containing a list of "key: value" pairs. Example: `{ "name": "wrench", "mass": "1.3kg", "count": "3" }`.
- !ruby/object:Api::Type::String
name: 'requestOrigin'
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
output: true
description: The origin of the quota preference request.
- !ruby/object:Api::Type::KeyValuePairs
name: 'dimensions'
default_from_api: true
description: |-
The dimensions that this quota preference applies to. The key of the map entry is the name of a dimension, such as "region", "zone", "network_id", and the value of the map entry is the dimension value. If a dimension is missing from the map of dimensions, the quota preference applies to all the dimension values except for those that have other quota preferences configured for the specific value.

NOTE: QuotaPreferences can only be applied across all values of "user" and "resource" dimension. Do not set values for "user" or "resource" in the dimension map.

Example: `{"provider": "Foo Inc"}` where "provider" is a service specific dimension.
- !ruby/object:Api::Type::String
name: 'etag'
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
output: true
description: |
The current etag of the quota preference. If an etag is provided on update and does not match the current server's etag of the quota preference, the request will be blocked and an ABORTED error will be returned. See https://google.aip.dev/134#etags for more details on etags.
- !ruby/object:Api::Type::String
name: 'createTime'
output: true
description: |
Create time stamp.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: `2014-10-02T15:01:23Z` and `2014-10-02T15:01:23.045123456Z`.
- !ruby/object:Api::Type::String
name: 'updateTime'
output: true
description: |
Update time stamp.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: `2014-10-02T15:01:23Z` and `2014-10-02T15:01:23.045123456Z`.
- !ruby/object:Api::Type::Boolean
name: 'reconciling'
output: true
description: |
Is the quota preference pending Google Cloud approval and fulfillment.
- !ruby/object:Api::Type::String
name: 'justification'
ignore_read: true
description: The reason / justification for this quota preference.
- !ruby/object:Api::Type::String
name: 'contactEmail'
ignore_read: true
description: |-
An email address that can be used for quota related communication between the Google Cloud and the user in case the Google Cloud needs further information to make a decision on whether the user preferred quota can be granted.

The Google account for the email address must have quota update permission for the project, folder or organization this quota preference is for.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
// ignore read on this field
return d.Get("quota_config.0.annotations")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "google_cloud_quotas_quota_preference" "<%= ctx[:primary_resource_id] %>" {
parent = "projects/<%= ctx[:test_env_vars]['project'] %>"
name = "<%= ctx[:vars]['name'] %>"
dimensions = { region = "us-east1" }
service = "compute.googleapis.com"
quota_id = "CPUS-per-project-region"
contact_email = "[email protected]"
quota_config {
preferred_value = 200
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ import (
"github.com/hashicorp/terraform-provider-google/google/services/dataflow"
"github.com/hashicorp/terraform-provider-google/google/services/servicenetworking"
"github.com/hashicorp/terraform-provider-google/google/tpgiamresource"
<% if version == 'ga' -%> // https://github.com/hashicorp/terraform-provider-google/issues/15633 for details
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the other PRs merged, do we still need to remove this, or do we possibly need a rebase?

"github.com/hashicorp/terraform-provider-google/google/services/cloudquotas"
<% end -%>
)

// Datasources
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package cloudquotas_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 TestAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_update(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"org_id": envvar.GetTestOrgFromEnv(t),
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"time": {},
},
Steps: []resource.TestStep{
{
Config: testAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_basic(context),
},
{
ResourceName: "google_cloud_quotas_quota_preference.my_preference",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"parent", "quota_preference_id", "ignore_safety_checks", "contact_email"},
},
{
Config: testAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_increaseQuota(context),
},
{
ResourceName: "google_cloud_quotas_quota_preference.my_preference",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"parent", "quota_preference_id", "ignore_safety_checks", "contact_email", "justification", "quota_config.0.annotations"},
},
{
Config: testAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_decreaseQuota(context),
},
{
ResourceName: "google_cloud_quotas_quota_preference.my_preference",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"parent", "quota_preference_id", "ignore_safety_checks", "contact_email", "justification", "quota_config.0.annotations"},
},
},
})
}

func testAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_project" "new_project" {
project_id = "tf-test%{random_suffix}"
name = "tf-test%{random_suffix}"
org_id = "%{org_id}"
billing_account = "%{billing_account}"
}

resource "google_project_service" "cloudquotas" {
project = google_project.new_project.project_id
service = "cloudquotas.googleapis.com"
depends_on = [google_project.new_project]
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
}

resource "google_project_service" "compute" {
project = google_project.new_project.project_id
service = "compute.googleapis.com"
depends_on = [google_project.new_project]
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
}

resource "google_project_service" "billing" {
project = google_project.new_project.project_id
service = "cloudbilling.googleapis.com"
depends_on = [google_project.new_project]
}

resource "time_sleep" "wait_120_seconds" {
create_duration = "120s"
depends_on = [
google_project_service.cloudquotas,
google_project_service.compute,
google_project_service.billing,
]
}

resource "google_cloud_quotas_quota_preference" "my_preference"{
parent = "projects/${google_project.new_project.project_id}"
name = "compute_googleapis_com-CPUS-per-project_us-central1"
dimensions = { region = "us-central1" }
service = "compute.googleapis.com"
quota_id = "CPUS-per-project-region"
contact_email = "[email protected]"
quota_config {
preferred_value = 70
}
ignore_safety_checks = "QUOTA_DECREASE_PERCENTAGE_TOO_HIGH"
depends_on = [
time_sleep.wait_120_seconds
]
}
`, context)
}

func testAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_increaseQuota(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_project" "new_project" {
project_id = "tf-test%{random_suffix}"
name = "tf-test%{random_suffix}"
org_id = "%{org_id}"
billing_account = "%{billing_account}"
}

resource "google_project_service" "cloudquotas" {
project = google_project.new_project.project_id
service = "cloudquotas.googleapis.com"
depends_on = [google_project.new_project]
}

resource "google_project_service" "compute" {
project = google_project.new_project.project_id
service = "compute.googleapis.com"
depends_on = [google_project.new_project]
}

resource "google_project_service" "billing" {
project = google_project.new_project.project_id
service = "cloudbilling.googleapis.com"
depends_on = [google_project.new_project]
}

resource "google_cloud_quotas_quota_preference" "my_preference"{
contact_email = "[email protected]"
justification = "Ignore. Increase quota for Terraform testing."
quota_config {
preferred_value = 72
annotations = { label = "terraform" }
}
depends_on = [
google_project_service.cloudquotas,
google_project_service.compute,
google_project_service.billing,
]
}
`, context)
}

func testAccCloudQuotasQuotaPreference_cloudquotasQuotaPreferenceBasicExample_decreaseQuota(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_project" "new_project" {
project_id = "tf-test%{random_suffix}"
name = "tf-test%{random_suffix}"
org_id = "%{org_id}"
billing_account = "%{billing_account}"
}

resource "google_project_service" "cloudquotas" {
project = google_project.new_project.project_id
service = "cloudquotas.googleapis.com"
depends_on = [google_project.new_project]
}

resource "google_project_service" "compute" {
project = google_project.new_project.project_id
service = "compute.googleapis.com"
depends_on = [google_project.new_project]
}

resource "google_project_service" "billing" {
project = google_project.new_project.project_id
service = "cloudbilling.googleapis.com"
depends_on = [google_project.new_project]
}

resource "google_cloud_quotas_quota_preference" "my_preference"{
ignore_safety_checks = "QUOTA_DECREASE_PERCENTAGE_TOO_HIGH"
quota_config {
preferred_value = 65
}
depends_on = [
google_project_service.cloudquotas,
google_project_service.compute,
google_project_service.billing,
]
}
`, context)
}