From ccbd66997ec632905dd726015573a49dae2f2a45 Mon Sep 17 00:00:00 2001 From: wj-chen Date: Fri, 28 Jul 2023 14:05:13 -0700 Subject: [PATCH 001/476] Enhance BigQuery table schema input validation (#8460) * Enhance BigQuery table schema input validation * skip TestAccBigQueryTable_invalidSchemas in VCR test --- .../bigquery/resource_bigquery_table.go | 30 +++- .../tests/resource_bigquery_table_test.go | 134 ++++++++++++++++++ 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index dafd68aa86be..b95488961d3b 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -363,6 +363,32 @@ func resourceBigQueryTableSchemaCustomizeDiff(_ context.Context, d *schema.Resou return resourceBigQueryTableSchemaCustomizeDiffFunc(d) } +func validateBigQueryTableSchema(v interface{}, k string) (warnings []string, errs []error) { + if v == nil { + return + } + + if _, e := validation.StringIsJSON(v, k); e != nil { + errs = append(errs, e...) + return + } + + var jsonList []interface{} + if err := json.Unmarshal([]byte(v.(string)), &jsonList); err != nil { + errs = append(errs, fmt.Errorf("\"schema\" is not a JSON array: %s", err)) + return + } + + for _, v := range jsonList { + if v == nil { + errs = append(errs, errors.New("\"schema\" contains a nil element")) + return + } + } + + return +} + func ResourceBigQueryTable() *schema.Resource { return &schema.Resource{ Create: resourceBigQueryTableCreate, @@ -471,7 +497,7 @@ func ResourceBigQueryTable() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ValidateFunc: validation.StringIsJSON, + ValidateFunc: validateBigQueryTableSchema, StateFunc: func(v interface{}) string { json, _ := structure.NormalizeJsonString(v) return json @@ -739,7 +765,7 @@ func ResourceBigQueryTable() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validation.StringIsJSON, + ValidateFunc: validateBigQueryTableSchema, StateFunc: func(v interface{}) string { json, _ := structure.NormalizeJsonString(v) return json diff --git a/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go b/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go index e3b2d380b937..229d32af49d3 100644 --- a/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go @@ -586,6 +586,36 @@ func TestAccBigQueryExternalDataTable_CSV(t *testing.T) { }) } +func TestAccBigQueryExternalDataTable_CSV_WithSchema_InvalidSchemas(t *testing.T) { + t.Parallel() + + bucketName := testBucketName(t) + objectName := fmt.Sprintf("tf_test_%s.csv", RandString(t, 10)) + + datasetID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + + VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableFromGCSWithExternalDataConfigSchema(datasetID, tableID, bucketName, objectName, TEST_SIMPLE_CSV, TEST_INVALID_SCHEMA_NOT_JSON), + ExpectError: regexp.MustCompile("contains an invalid JSON"), + }, + { + Config: testAccBigQueryTableFromGCSWithExternalDataConfigSchema(datasetID, tableID, bucketName, objectName, TEST_SIMPLE_CSV, TEST_INVALID_SCHEMA_NOT_JSON_LIST), + ExpectError: regexp.MustCompile("\"schema\" is not a JSON array"), + }, + { + Config: testAccBigQueryTableFromGCSWithExternalDataConfigSchema(datasetID, tableID, bucketName, objectName, TEST_SIMPLE_CSV, TEST_INVALID_SCHEMA_JSON_LIST_WITH_NULL_ELEMENT), + ExpectError: regexp.MustCompile("\"schema\" contains a nil element"), + }, + }, + }) +} + func TestAccBigQueryExternalDataTable_CSV_WithSchemaAndConnectionID_UpdateNoConnectionID(t *testing.T) { t.Parallel() @@ -917,6 +947,35 @@ func TestAccBigQueryTable_emptySchema(t *testing.T) { }) } +func TestAccBigQueryTable_invalidSchemas(t *testing.T) { + t.Parallel() + // Not an acceptance test. + acctest.SkipIfVcr(t) + + datasetID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + + VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableWithSchema(datasetID, tableID, TEST_INVALID_SCHEMA_NOT_JSON), + ExpectError: regexp.MustCompile("contains an invalid JSON"), + }, + { + Config: testAccBigQueryTableWithSchema(datasetID, tableID, TEST_INVALID_SCHEMA_NOT_JSON_LIST), + ExpectError: regexp.MustCompile("\"schema\" is not a JSON array"), + }, + { + Config: testAccBigQueryTableWithSchema(datasetID, tableID, TEST_INVALID_SCHEMA_JSON_LIST_WITH_NULL_ELEMENT), + ExpectError: regexp.MustCompile("\"schema\" contains a nil element"), + }, + }, + }) +} + func testAccCheckBigQueryExtData(t *testing.T, expectedQuoteChar string) resource.TestCheckFunc { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { @@ -1984,6 +2043,45 @@ resource "google_bigquery_table" "test" { `, datasetID, bucketName, objectName, content, tableID, schema) } +func testAccBigQueryTableFromGCSWithExternalDataConfigSchema(datasetID, tableID, bucketName, objectName, content, schema string) string { + return fmt.Sprintf(` +resource "google_bigquery_dataset" "test" { + dataset_id = "%s" +} +resource "google_storage_bucket" "test" { + name = "%s" + location = "US" + force_destroy = true +} +resource "google_storage_bucket_object" "test" { + name = "%s" + content = < Date: Fri, 4 Aug 2023 13:50:46 -0400 Subject: [PATCH 002/476] Breaking changes for Firebase apps deletion policy (#8458) --- mmv1/products/firebase/AndroidApp.yaml | 9 +-- mmv1/products/firebase/AppleApp.yaml | 10 ++-- mmv1/products/firebase/WebApp.yaml | 13 ++-- .../examples/firebase_web_app_basic.tf.erb | 22 +------ .../examples/firebasehosting_site_full.tf.erb | 1 - ...source_google_firebase_web_app_test.go.erb | 1 - ...resource_firebase_hosting_site_test.go.erb | 2 - .../resource_firebase_web_app_test.go.erb | 60 ++++++++----------- 8 files changed, 42 insertions(+), 76 deletions(-) diff --git a/mmv1/products/firebase/AndroidApp.yaml b/mmv1/products/firebase/AndroidApp.yaml index 17f46aeb37f2..03a5c194dfeb 100644 --- a/mmv1/products/firebase/AndroidApp.yaml +++ b/mmv1/products/firebase/AndroidApp.yaml @@ -64,7 +64,6 @@ examples: vars: display_name: 'Display Name Basic' test_env_vars: - org_id: :ORG_ID project_id: :PROJECT_NAME test_vars_overrides: package_name: '"android.package.app" + acctest.RandString(t, 4)' @@ -73,14 +72,16 @@ examples: - project - deletion_policy virtual_fields: - # TODO: make this an enum in a future major version. If using this field as a reference, look at PerInstanceConfig's minimal_action field for enum configuration. - - !ruby/object:Api::Type::String + - !ruby/object:Api::Type::Enum name: 'deletion_policy' description: | (Optional) Set to `ABANDON` to allow the AndroidApp to be untracked from terraform state rather than deleted upon `terraform destroy`. This is useful because the AndroidApp may be serving traffic. Set to `DELETE` to delete the AndroidApp. Defaults to `DELETE`. - default_value: DELETE + default_value: :DELETE + values: + - :DELETE + - :ABANDON custom_code: !ruby/object:Provider::Terraform::CustomCode custom_delete: templates/terraform/custom_delete/firebase_app_deletion_policy.erb properties: diff --git a/mmv1/products/firebase/AppleApp.yaml b/mmv1/products/firebase/AppleApp.yaml index 7653470da1c1..82079249edab 100644 --- a/mmv1/products/firebase/AppleApp.yaml +++ b/mmv1/products/firebase/AppleApp.yaml @@ -65,7 +65,6 @@ examples: display_name: 'Display Name Basic' bundle_id: 'apple.app.12345' test_env_vars: - org_id: :ORG_ID project_id: :PROJECT_NAME test_vars_overrides: display_name: '"tf-test Display Name Basic"' @@ -79,7 +78,6 @@ examples: app_store_id: '12345' team_id: '9987654321' # Has to be a 10-digit number. test_env_vars: - org_id: :ORG_ID project_id: :PROJECT_NAME test_vars_overrides: app_store_id: '12345' @@ -89,14 +87,16 @@ examples: - project - deletion_policy virtual_fields: - # TODO: make this an enum in a future major version. If using this field as a reference, look at PerInstanceConfig's minimal_action field for enum configuration. - - !ruby/object:Api::Type::String + - !ruby/object:Api::Type::Enum name: 'deletion_policy' description: | (Optional) Set to `ABANDON` to allow the Apple to be untracked from terraform state rather than deleted upon `terraform destroy`. This is useful because the Apple may be serving traffic. Set to `DELETE` to delete the Apple. Defaults to `DELETE`. - default_value: DELETE + default_value: :DELETE + values: + - :DELETE + - :ABANDON custom_code: !ruby/object:Provider::Terraform::CustomCode custom_delete: templates/terraform/custom_delete/firebase_app_deletion_policy.erb properties: diff --git a/mmv1/products/firebase/WebApp.yaml b/mmv1/products/firebase/WebApp.yaml index 5e11372645ac..df07eb5f9ca5 100644 --- a/mmv1/products/firebase/WebApp.yaml +++ b/mmv1/products/firebase/WebApp.yaml @@ -65,23 +65,24 @@ examples: vars: display_name: 'Display Name Basic' bucket_name: 'fb-webapp-' - project_name: "my-project" test_env_vars: - org_id: :ORG_ID + project_id: :PROJECT_NAME test_vars_overrides: display_name: '"tf-test Display Name Basic"' ignore_read_extra: - project - deletion_policy virtual_fields: - # TODO: make this an enum in a future major version. If using this field as a reference, look at PerInstanceConfig's minimal_action field for enum configuration. - - !ruby/object:Api::Type::String + - !ruby/object:Api::Type::Enum name: 'deletion_policy' description: | Set to `ABANDON` to allow the WebApp to be untracked from terraform state rather than deleted upon `terraform destroy`. This is useful becaue the WebApp may be - serving traffic. Set to `DELETE` to delete the WebApp. Default to `ABANDON` - default_value: ABANDON + serving traffic. Set to `DELETE` to delete the WebApp. Default to `DELETE` + default_value: :DELETE + values: + - :DELETE + - :ABANDON custom_code: !ruby/object:Provider::Terraform::CustomCode custom_delete: templates/terraform/custom_delete/firebase_app_deletion_policy.erb properties: diff --git a/mmv1/templates/terraform/examples/firebase_web_app_basic.tf.erb b/mmv1/templates/terraform/examples/firebase_web_app_basic.tf.erb index c75c49c821d6..46d98f831900 100644 --- a/mmv1/templates/terraform/examples/firebase_web_app_basic.tf.erb +++ b/mmv1/templates/terraform/examples/firebase_web_app_basic.tf.erb @@ -1,27 +1,7 @@ -resource "google_project" "default" { - provider = google-beta - - project_id = "<%= ctx[:vars]['project_name'] %>" - name = "<%= ctx[:vars]['project_name'] %>" - org_id = "<%= ctx[:test_env_vars]['org_id'] %>" - - labels = { - "firebase" = "enabled" - } -} - -resource "google_firebase_project" "default" { - provider = google-beta - project = google_project.default.project_id -} - resource "google_firebase_web_app" "<%= ctx[:primary_resource_id] %>" { provider = google-beta - project = google_project.default.project_id + project = "<%= ctx[:test_env_vars]['project_id'] %>" display_name = "<%= ctx[:vars]['display_name'] %>" - deletion_policy = "DELETE" - - depends_on = [google_firebase_project.default] } data "google_firebase_web_app_config" "basic" { diff --git a/mmv1/templates/terraform/examples/firebasehosting_site_full.tf.erb b/mmv1/templates/terraform/examples/firebasehosting_site_full.tf.erb index 57c88044615e..f436a7264428 100644 --- a/mmv1/templates/terraform/examples/firebasehosting_site_full.tf.erb +++ b/mmv1/templates/terraform/examples/firebasehosting_site_full.tf.erb @@ -2,7 +2,6 @@ resource "google_firebase_web_app" "default" { provider = google-beta project = "<%= ctx[:test_env_vars]['project_id'] %>" display_name = "<%= ctx[:vars]['display_name'] %>" - deletion_policy = "DELETE" } resource "google_firebase_hosting_site" "full" { diff --git a/mmv1/third_party/terraform/tests/data_source_google_firebase_web_app_test.go.erb b/mmv1/third_party/terraform/tests/data_source_google_firebase_web_app_test.go.erb index 55a476684a91..084e3b2004b9 100644 --- a/mmv1/third_party/terraform/tests/data_source_google_firebase_web_app_test.go.erb +++ b/mmv1/third_party/terraform/tests/data_source_google_firebase_web_app_test.go.erb @@ -44,7 +44,6 @@ func testAccDataSourceGoogleFirebaseWebApp(context map[string]interface{}) strin resource "google_firebase_web_app" "my_app" { project = "%{project_id}" display_name = "%{display_name}" - deletion_policy = "DELETE" } data "google_firebase_web_app" "my_app" { diff --git a/mmv1/third_party/terraform/tests/resource_firebase_hosting_site_test.go.erb b/mmv1/third_party/terraform/tests/resource_firebase_hosting_site_test.go.erb index 6647c063e5f4..e8b9097aa2e1 100644 --- a/mmv1/third_party/terraform/tests/resource_firebase_hosting_site_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_firebase_hosting_site_test.go.erb @@ -52,7 +52,6 @@ resource "google_firebase_web_app" "before" { provider = google-beta project = "%{project_id}" display_name = "tf-test Test web app before for Firebase Hosting" - deletion_policy = "DELETE" } resource "google_firebase_hosting_site" "update" { @@ -70,7 +69,6 @@ resource "google_firebase_web_app" "after" { provider = google-beta project = "%{project_id}" display_name = "tf-test Test web app after for Firebase Hosting" - deletion_policy = "DELETE" } resource "google_firebase_hosting_site" "update" { diff --git a/mmv1/third_party/terraform/tests/resource_firebase_web_app_test.go.erb b/mmv1/third_party/terraform/tests/resource_firebase_web_app_test.go.erb index 68ffd72efcd4..c1c87f6c1478 100644 --- a/mmv1/third_party/terraform/tests/resource_firebase_web_app_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_firebase_web_app_test.go.erb @@ -22,30 +22,19 @@ func TestAccFirebaseWebApp_firebaseWebAppFull(t *testing.T) { t.Parallel() context := map[string]interface{}{ - "org_id": envvar.GetTestOrgFromEnv(t), + "project_id": envvar.GetTestProjectFromEnv(), "random_suffix": acctest.RandString(t, 10), "display_name": "tf-test Display Name N", } acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t), Steps: []resource.TestStep{ { - ExternalProviders: map[string]resource.ExternalProvider{ - "google": { - VersionConstraint: "4.58.0", - Source: "hashicorp/google<%= "-" + version unless version == 'ga' -%>", - }, - }, Config: testAccFirebaseWebApp_firebaseWebAppFull(context, ""), }, { - ExternalProviders: map[string]resource.ExternalProvider{ - "google": { - VersionConstraint: "4.58.0", - Source: "hashicorp/google<%= "-" + version unless version == 'ga' -%>", - }, - }, Config: testAccFirebaseWebApp_firebaseWebAppFull(context, "2"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("data.google_firebase_web_app_config.default", "api_key"), @@ -54,11 +43,9 @@ func TestAccFirebaseWebApp_firebaseWebAppFull(t *testing.T) { ), }, { - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), Config: testAccFirebaseWebApp_firebaseWebAppFull(context, ""), }, { - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), Config: testAccFirebaseWebApp_firebaseWebAppFull(context, "2"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("data.google_firebase_web_app_config.default", "api_key"), @@ -73,28 +60,11 @@ func TestAccFirebaseWebApp_firebaseWebAppFull(t *testing.T) { func testAccFirebaseWebApp_firebaseWebAppFull(context map[string]interface{}, update string) string { context["display_name"] = context["display_name"].(string) + update return acctest.Nprintf(` -resource "google_project" "default" { - provider = google-beta - - project_id = "tf-test%{random_suffix}" - name = "tf-test%{random_suffix}" - org_id = "%{org_id}" - labels = { - "firebase" = "enabled" - } -} - -resource "google_firebase_project" "default" { - provider = google-beta - project = google_project.default.project_id -} - resource "google_firebase_web_app" "default" { provider = google-beta - project = google_project.default.project_id + project = "%{project_id}" display_name = "%{display_name} %{random_suffix}" - - depends_on = [google_firebase_project.default] + deletion_policy = "DELETE" } data "google_firebase_web_app_config" "default" { @@ -108,7 +78,7 @@ func TestAccFirebaseWebApp_firebaseWebAppSkipDelete(t *testing.T) { t.Parallel() context := map[string]interface{}{ - "project_id": envvar.GetTestProjectFromEnv(), + "org_id": envvar.GetTestOrgFromEnv(t), "random_suffix": acctest.RandString(t, 10), "display_name": "tf-test Display Name N", } @@ -132,11 +102,29 @@ func TestAccFirebaseWebApp_firebaseWebAppSkipDelete(t *testing.T) { } func testAccFirebaseWebApp_firebaseWebAppSkipDelete(context map[string]interface{}, update string) string { + // Create a new project so we can clean up the project entirely return acctest.Nprintf(` +resource "google_project" "default" { + provider = google-beta + + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + labels = { + "firebase" = "enabled" + } +} + +resource "google_firebase_project" "default" { + provider = google-beta + project = google_project.default.project_id +} + resource "google_firebase_web_app" "skip_delete" { provider = google-beta - project = "%{project_id}" + project = google_firebase_project.default.project display_name = "%{display_name} %{random_suffix}" + deletion_policy = "ABANDON" } `, context) } From a102bc63620dc24315001f228ba01190f1dbdba7 Mon Sep 17 00:00:00 2001 From: Yanwei Guo Date: Tue, 8 Aug 2023 09:30:45 -0700 Subject: [PATCH 003/476] remove deprecated (#8529) --- mmv1/products/cloudrunv2/Job.yaml | 158 -------------------------- mmv1/products/cloudrunv2/Service.yaml | 15 --- 2 files changed, 173 deletions(-) diff --git a/mmv1/products/cloudrunv2/Job.yaml b/mmv1/products/cloudrunv2/Job.yaml index 01f9e8499d64..f2361164420e 100644 --- a/mmv1/products/cloudrunv2/Job.yaml +++ b/mmv1/products/cloudrunv2/Job.yaml @@ -337,164 +337,6 @@ properties: name: 'workingDir' description: |- Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. - - !ruby/object:Api::Type::NestedObject - name: 'livenessProbe' - description: |- - Periodic probe of container liveness. Container will be restarted if the probe fails. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - This field is not supported in Cloud Run Job currently. - deprecation_message: - Cloud Run Job does not support liveness probe and - `liveness_probe` field will be removed in a future major - release. - properties: - - !ruby/object:Api::Type::Integer - name: 'initialDelaySeconds' - description: |- - Number of seconds after the container has started before the probe is initiated. Defaults to 0 seconds. Minimum value is 0. Maximum value for liveness probe is 3600. Maximum value for startup probe is 240. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - default_value: 0 - - !ruby/object:Api::Type::Integer - name: 'timeoutSeconds' - description: |- - Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. Maximum value is 3600. Must be smaller than periodSeconds. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - default_value: 1 - - !ruby/object:Api::Type::Integer - name: 'periodSeconds' - description: |- - How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. Maximum value for liveness probe is 3600. Maximum value for startup probe is 240. Must be greater or equal than timeoutSeconds - default_value: 10 - - !ruby/object:Api::Type::Integer - name: 'failureThreshold' - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. - default_value: 3 - - !ruby/object:Api::Type::NestedObject - name: 'httpGet' - description: |- - HTTPGet specifies the http request to perform. Exactly one of HTTPGet or TCPSocket must be specified. - send_empty_value: true - allow_empty_object: - true - # exactly_one_of: - # - template.0.template.0.containers.0.livenessProbe.0.httpGet - # - template.0.template.0.containers.0.livenessProbe.0.tcpSocket - properties: - - !ruby/object:Api::Type::String - name: 'path' - default_value: '/' - description: |- - Path to access on the HTTP server. Defaults to '/'. - - !ruby/object:Api::Type::Array - name: httpHeaders - description: |- - Custom headers to set in the request. HTTP allows repeated headers. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: name - required: true - description: |- - The header field name - - !ruby/object:Api::Type::String - name: value - description: |- - The header field value - default_value: '' - send_empty_value: true - - !ruby/object:Api::Type::NestedObject - name: 'tcpSocket' - description: |- - TCPSocket specifies an action involving a TCP port. Exactly one of HTTPGet or TCPSocket must be specified. - send_empty_value: true - allow_empty_object: - true - # exactly_one_of: - # - template.0.template.0.containers.0.livenessProbe.0.httpGet - # - template.0.template.0.containers.0.livenessProbe.0.tcpSocket - properties: - - !ruby/object:Api::Type::Integer - name: port - description: |- - Port number to access on the container. Must be in the range 1 to 65535. If not specified, defaults to 8080. - - !ruby/object:Api::Type::NestedObject - name: 'startupProbe' - description: |- - Startup probe of application within the container. All other probes are disabled if a startup probe is provided, until it succeeds. Container will not be added to service endpoints if the probe fails. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - This field is not supported in Cloud Run Job currently. - deprecation_message: - Cloud Run Job does not support startup probe and - `startup_probe` field will be removed in a future major - release. - default_from_api: true - properties: - - !ruby/object:Api::Type::Integer - name: 'initialDelaySeconds' - description: |- - Number of seconds after the container has started before the probe is initiated. Defaults to 0 seconds. Minimum value is 0. Maximum value for liveness probe is 3600. Maximum value for startup probe is 240. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - default_value: 0 - - !ruby/object:Api::Type::Integer - name: 'timeoutSeconds' - description: |- - Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. Maximum value is 3600. Must be smaller than periodSeconds. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - default_value: 1 - - !ruby/object:Api::Type::Integer - name: 'periodSeconds' - description: |- - How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. Maximum value for liveness probe is 3600. Maximum value for startup probe is 240. Must be greater or equal than timeoutSeconds - default_value: 10 - - !ruby/object:Api::Type::Integer - name: 'failureThreshold' - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. - default_value: 3 - - !ruby/object:Api::Type::NestedObject - name: 'httpGet' - description: |- - HTTPGet specifies the http request to perform. Exactly one of HTTPGet or TCPSocket must be specified. - send_empty_value: true - allow_empty_object: - true - # exactly_one_of: - # - template.0.template.0.containers.startupProbe.0.httpGet - # - template.0.template.0.containers.startupProbe.0.tcpSocket - properties: - - !ruby/object:Api::Type::String - name: 'path' - default_value: '/' - description: |- - Path to access on the HTTP server. Defaults to '/'. - - !ruby/object:Api::Type::Array - name: 'httpHeaders' - description: |- - Custom headers to set in the request. HTTP allows repeated headers. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: name - required: true - description: |- - The header field name - - !ruby/object:Api::Type::String - name: value - description: |- - The header field value - default_value: '' - send_empty_value: true - - !ruby/object:Api::Type::NestedObject - name: 'tcpSocket' - description: |- - TCPSocket specifies an action involving a TCP port. Exactly one of HTTPGet or TCPSocket must be specified. - send_empty_value: true - allow_empty_object: - true - # exactly_one_of: - # - template.0.template.0.containers.startupProbe.0.httpGet - # - template.0.template.0.containers.startupProbe.0.tcpSocket - properties: - - !ruby/object:Api::Type::Integer - name: port - description: |- - Port number to access on the container. Must be in the range 1 to 65535. If not specified, defaults to 8080. - default_from_api: true - !ruby/object:Api::Type::Array name: 'volumes' description: |- diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index 5ba508fc9b42..66953043edc3 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -466,21 +466,6 @@ properties: The header field value default_value: '' send_empty_value: true - - !ruby/object:Api::Type::NestedObject - name: 'tcpSocket' - description: |- - TCPSocket specifies an action involving a TCP port. This field is not supported in liveness probe currently. - deprecation_message: - Cloud Run does not support tcp socket in liveness probe and - `liveness_probe.tcp_socket` field will be removed in a - future major release. - send_empty_value: true - allow_empty_object: true - properties: - - !ruby/object:Api::Type::Integer - name: port - description: |- - Port number to access on the container. Must be in the range 1 to 65535. If not specified, defaults to 8080. - !ruby/object:Api::Type::NestedObject name: grpc description: |- From 87e4f293f0030189f8ee24f20a20d7fa57eb2cc8 Mon Sep 17 00:00:00 2001 From: wj-chen Date: Wed, 9 Aug 2023 10:30:22 -0700 Subject: [PATCH 004/476] Enforce mutual exclusivity among view, materialized view, and schema in BigQuery table config (#7973) * Enforce mutual exclusivity among view, materialized view, and schema in BigQuery table config * fix merge conflict * fix field specification and add a VCR skip for the new acceptance test * skip VCR for MaterializedView_WithView test too --- .../bigquery/resource_bigquery_table.go | 45 ++--- .../tests/resource_bigquery_table_test.go | 163 ++++++++++++++++-- 2 files changed, 159 insertions(+), 49 deletions(-) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index b95488961d3b..8048027c14e0 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -761,6 +761,7 @@ func ResourceBigQueryTable() *schema.Resource { }, // Schema: [Optional] Describes the schema of this table. + // Schema is mutually exclusive with View and Materialized View. "schema": { Type: schema.TypeString, Optional: true, @@ -772,8 +773,10 @@ func ResourceBigQueryTable() *schema.Resource { }, DiffSuppressFunc: bigQueryTableSchemaDiffSuppress, Description: `A JSON schema for the table.`, + ConflictsWith: []string{"view", "materialized_view"}, }, // View: [Optional] If specified, configures this table as a view. + // View is mutually exclusive with Schema and Materialized View. "view": { Type: schema.TypeList, Optional: true, @@ -800,9 +803,11 @@ func ResourceBigQueryTable() *schema.Resource { }, }, }, + ConflictsWith: []string{"schema", "materialized_view"}, }, // Materialized View: [Optional] If specified, configures this table as a materialized view. + // Materialized View is mutually exclusive with Schema and View. "materialized_view": { Type: schema.TypeList, Optional: true, @@ -839,6 +844,7 @@ func ResourceBigQueryTable() *schema.Resource { }, }, }, + ConflictsWith: []string{"schema", "view"}, }, // TimePartitioning: [Experimental] If specified, configures time-based @@ -1170,41 +1176,16 @@ func resourceBigQueryTableCreate(d *schema.ResourceData, meta interface{}) error datasetID := d.Get("dataset_id").(string) - if table.View != nil && table.Schema != nil { + log.Printf("[INFO] Creating BigQuery table: %s", table.TableReference.TableId) - log.Printf("[INFO] Removing schema from table definition because big query does not support setting schema on view creation") - schemaBack := table.Schema - table.Schema = nil - - log.Printf("[INFO] Creating BigQuery table: %s without schema", table.TableReference.TableId) - - res, err := config.NewBigQueryClient(userAgent).Tables.Insert(project, datasetID, table).Do() - if err != nil { - return err - } - - log.Printf("[INFO] BigQuery table %s has been created", res.Id) - d.SetId(fmt.Sprintf("projects/%s/datasets/%s/tables/%s", res.TableReference.ProjectId, res.TableReference.DatasetId, res.TableReference.TableId)) - - table.Schema = schemaBack - log.Printf("[INFO] Updating BigQuery table: %s with schema", table.TableReference.TableId) - if _, err = config.NewBigQueryClient(userAgent).Tables.Update(project, datasetID, res.TableReference.TableId, table).Do(); err != nil { - return err - } - - log.Printf("[INFO] BigQuery table %s has been update with schema", res.Id) - } else { - log.Printf("[INFO] Creating BigQuery table: %s", table.TableReference.TableId) - - res, err := config.NewBigQueryClient(userAgent).Tables.Insert(project, datasetID, table).Do() - if err != nil { - return err - } - - log.Printf("[INFO] BigQuery table %s has been created", res.Id) - d.SetId(fmt.Sprintf("projects/%s/datasets/%s/tables/%s", res.TableReference.ProjectId, res.TableReference.DatasetId, res.TableReference.TableId)) + res, err := config.NewBigQueryClient(userAgent).Tables.Insert(project, datasetID, table).Do() + if err != nil { + return err } + log.Printf("[INFO] BigQuery table %s has been created", res.Id) + d.SetId(fmt.Sprintf("projects/%s/datasets/%s/tables/%s", res.TableReference.ProjectId, res.TableReference.DatasetId, res.TableReference.TableId)) + return resourceBigQueryTableRead(d, meta) } diff --git a/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go b/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go index 229d32af49d3..85299b40fd33 100644 --- a/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go @@ -367,22 +367,8 @@ func TestAccBigQueryTable_WithViewAndSchema(t *testing.T) { CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccBigQueryTableWithViewAndSchema(datasetID, tableID, "table description1"), - }, - { - ResourceName: "google_bigquery_table.test", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection"}, - }, - { - Config: testAccBigQueryTableWithViewAndSchema(datasetID, tableID, "table description2"), - }, - { - ResourceName: "google_bigquery_table.test", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection"}, + Config: testAccBigQueryTableWithViewAndSchema(datasetID, tableID, "table description"), + ExpectError: regexp.MustCompile("\"view\": conflicts with schema"), }, }, }) @@ -487,6 +473,52 @@ func TestAccBigQueryTable_MaterializedView_DailyTimePartioning_Update(t *testing }) } +func TestAccBigQueryTable_MaterializedView_WithSchema(t *testing.T) { + t.Parallel() + // Pending VCR support in https://github.com/hashicorp/terraform-provider-google/issues/15427. + acctest.SkipIfVcr(t) + + datasetID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + materializedViewID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + query := fmt.Sprintf("SELECT some_int FROM `%s.%s`", datasetID, tableID) + + VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableWithMatViewAndSchema(datasetID, tableID, materializedViewID, query), + ExpectError: regexp.MustCompile("\"materialized_view\": conflicts with schema"), + }, + }, + }) +} + +func TestAccBigQueryTable_MaterializedView_WithView(t *testing.T) { + t.Parallel() + // Pending VCR support in https://github.com/hashicorp/terraform-provider-google/issues/15427. + acctest.SkipIfVcr(t) + + datasetID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + materializedViewID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) + query := fmt.Sprintf("SELECT some_int FROM `%s.%s`", datasetID, tableID) + + VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableWithMatViewAndView(datasetID, tableID, materializedViewID, query), + ExpectError: regexp.MustCompile("\"materialized_view\": conflicts with view"), + }, + }, + }) +} + func TestAccBigQueryExternalDataTable_parquet(t *testing.T) { t.Parallel() @@ -949,7 +981,7 @@ func TestAccBigQueryTable_emptySchema(t *testing.T) { func TestAccBigQueryTable_invalidSchemas(t *testing.T) { t.Parallel() - // Not an acceptance test. + // Pending VCR support in https://github.com/hashicorp/terraform-provider-google/issues/15427. acctest.SkipIfVcr(t) datasetID := fmt.Sprintf("tf_test_%s", RandString(t, 10)) @@ -1554,6 +1586,103 @@ resource "google_bigquery_table" "mv_test" { `, datasetID, tableID, mViewID, enable_refresh, refresh_interval, query) } +func testAccBigQueryTableWithMatViewAndSchema(datasetID, tableID, mViewID, query string) string { + return fmt.Sprintf(` +resource "google_bigquery_dataset" "test" { + dataset_id = "%s" +} + +resource "google_bigquery_table" "test" { + deletion_protection = false + table_id = "%s" + dataset_id = google_bigquery_dataset.test.dataset_id + + schema = < Date: Fri, 11 Aug 2023 10:46:58 -0700 Subject: [PATCH 005/476] Bugfix: Use API's default value for enableEndpointIndependentMapping (#8600) Instead of using a hardcode default of `false` for `enableEndpointIndependentMapping`, use the default value from the API. --- mmv1/products/compute/RouterNat.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mmv1/products/compute/RouterNat.yaml b/mmv1/products/compute/RouterNat.yaml index 9585438f70b7..7f9689035c9b 100644 --- a/mmv1/products/compute/RouterNat.yaml +++ b/mmv1/products/compute/RouterNat.yaml @@ -371,7 +371,7 @@ properties: - !ruby/object:Api::Type::Boolean name: enableEndpointIndependentMapping description: | - Specifies if endpoint independent mapping is enabled. This is enabled by default. For more information - see the [official documentation](https://cloud.google.com/nat/docs/overview#specs-rfcs). - default_value: true + Enable endpoint independent mapping. + For more information see the [official documentation](https://cloud.google.com/nat/docs/overview#specs-rfcs). + default_from_api: true send_empty_value: true From 0fc437a08f8abd6a942d58a28abbe1ba24aae77f Mon Sep 17 00:00:00 2001 From: Saurabh Maurya Date: Tue, 15 Aug 2023 08:15:06 -0700 Subject: [PATCH 006/476] Remove dataprofileresult and dataqualityresult (#8583) --- mmv1/products/dataplex/Datascan.yaml | 381 --------------------------- 1 file changed, 381 deletions(-) diff --git a/mmv1/products/dataplex/Datascan.yaml b/mmv1/products/dataplex/Datascan.yaml index e788f3f39dbd..8c7062edc981 100644 --- a/mmv1/products/dataplex/Datascan.yaml +++ b/mmv1/products/dataplex/Datascan.yaml @@ -413,384 +413,3 @@ properties: name: 'rowFilter' description: | A filter applied to all rows in a single DataScan job. The filter needs to be a valid SQL expression for a WHERE clause in BigQuery standard SQL syntax. Example: col1 >= 0 AND col2 < 10 - - !ruby/object:Api::Type::NestedObject - name: 'dataQualityResult' - output: true - description: | - The result of the data quality scan. - properties: - - !ruby/object:Api::Type::Boolean - name: 'passed' - output: true - description: | - Overall data quality result -- true if all rules passed. - - !ruby/object:Api::Type::Array - name: 'dimensions' - description: | - A list of results at the dimension level. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::Boolean - name: 'passed' - description: | - Whether the dimension passed or failed. - - !ruby/object:Api::Type::Array - name: 'rules' - output: true - description: | - A list of all the rules in a job, and their results. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::NestedObject - name: 'rule' - output: true - description: | - The rule specified in the DataQualitySpec, as is. - properties: - - !ruby/object:Api::Type::String - name: 'column' - description: | - The unnested column which this rule is evaluated against. - - !ruby/object:Api::Type::Boolean - name: 'ignoreNull' - description: | - Rows with null values will automatically fail a rule, unless ignoreNull is true. In that case, such null rows are trivially considered passing. Only applicable to ColumnMap rules. - - !ruby/object:Api::Type::String - name: 'dimension' - description: | - The dimension a rule belongs to. Results are also aggregated at the dimension level. Supported dimensions are ["COMPLETENESS", "ACCURACY", "CONSISTENCY", "VALIDITY", "UNIQUENESS", "INTEGRITY"] - - !ruby/object:Api::Type::Integer - name: 'threshold' - description: | - The minimum ratio of passing_rows / total_rows required to pass this rule, with a range of [0.0, 1.0]. 0 indicates default value (i.e. 1.0). - - !ruby/object:Api::Type::NestedObject - name: 'rangeExpectation' - output: true - description: | - ColumnMap rule which evaluates whether each column value lies between a specified range. - properties: - - !ruby/object:Api::Type::String - name: 'minValue' - description: | - The minimum column value allowed for a row to pass this validation. At least one of minValue and maxValue need to be provided. - - !ruby/object:Api::Type::String - name: maxValue - description: | - The maximum column value allowed for a row to pass this validation. At least one of minValue and maxValue need to be provided. - - !ruby/object:Api::Type::Boolean - name: 'strictMinEnabled' - default_value: false - description: | - Whether each value needs to be strictly greater than ('>') the minimum, or if equality is allowed. - Only relevant if a minValue has been defined. Default = false. - - !ruby/object:Api::Type::Boolean - name: 'strictMaxEnabled' - default_value: false - description: | - Whether each value needs to be strictly lesser than ('<') the maximum, or if equality is allowed. - Only relevant if a maxValue has been defined. Default = false. - - !ruby/object:Api::Type::NestedObject - name: 'nonNullExpectation' - output: true - allow_empty_object: true - description: | - ColumnMap rule which evaluates whether each column value is null. - properties: [] - - !ruby/object:Api::Type::NestedObject - name: 'setExpectation' - output: true - description: | - ColumnMap rule which evaluates whether each column value is contained by a specified set. - properties: - - !ruby/object:Api::Type::Array - name: 'values' - description: | - Expected values for the column value. - item_type: Api::Type::String - - !ruby/object:Api::Type::NestedObject - name: 'regexExpectation' - output: true - description: | - ColumnMap rule which evaluates whether each column value matches a specified regex. - properties: - - !ruby/object:Api::Type::String - name: 'regex' - description: | - A regular expression the column value is expected to match. - - !ruby/object:Api::Type::NestedObject - name: 'uniquenessExpectation' - output: true - allow_empty_object: true - description: | - ColumnAggregate rule which evaluates whether the column has duplicates. - properties: [] - - !ruby/object:Api::Type::NestedObject - name: 'statisticRangeExpectation' - output: true - description: | - ColumnAggregate rule which evaluates whether the column aggregate statistic lies between a specified range. - properties: - - !ruby/object:Api::Type::Enum - name: 'statistic' - description: | - column statistics. - values: - - :STATISTIC_UNDEFINED - - :MEAN - - :MIN - - :MAX - - !ruby/object:Api::Type::String - name: 'minValue' - description: | - The minimum column statistic value allowed for a row to pass this validation. - At least one of minValue and maxValue need to be provided. - - !ruby/object:Api::Type::String - name: 'maxValue' - description: | - The maximum column statistic value allowed for a row to pass this validation. - At least one of minValue and maxValue need to be provided. - - !ruby/object:Api::Type::Boolean - name: 'strictMinEnabled' - description: | - Whether column statistic needs to be strictly greater than ('>') the minimum, or if equality is allowed. - Only relevant if a minValue has been defined. Default = false. - - !ruby/object:Api::Type::Boolean - name: 'strictMaxEnabled' - description: | - Whether column statistic needs to be strictly lesser than ('<') the maximum, or if equality is allowed. - Only relevant if a maxValue has been defined. Default = false. - - !ruby/object:Api::Type::NestedObject - name: 'rowConditionExpectation' - output: true - description: | - Table rule which evaluates whether each row passes the specified condition. - properties: - - !ruby/object:Api::Type::String - name: 'sqlExpression' - description: | - The SQL expression. - - !ruby/object:Api::Type::NestedObject - name: 'tableConditionExpectation' - output: true - description: | - Table rule which evaluates whether the provided expression is true. - properties: - - !ruby/object:Api::Type::String - name: 'sqlExpression' - description: | - The SQL expression. - - !ruby/object:Api::Type::Boolean - name: 'passed' - output: true - description: | - Whether the rule passed or failed. - - !ruby/object:Api::Type::String - name: 'evaluatedCount' - output: true - description: | - The number of rows a rule was evaluated against. This field is only valid for ColumnMap type rules. - Evaluated count can be configured to either - 1. include all rows (default) - with null rows automatically failing rule evaluation, or - 2. exclude null rows from the evaluatedCount, by setting ignore_nulls = true. - - !ruby/object:Api::Type::String - name: 'passedCount' - output: true - description: | - The number of rows which passed a rule evaluation. This field is only valid for ColumnMap type rules. - - !ruby/object:Api::Type::String - name: 'nullCount' - output: true - description: | - The number of rows with null values in the specified column. - - !ruby/object:Api::Type::Integer - name: 'passRatio' - output: true - description: | - The ratio of passedCount / evaluatedCount. This field is only valid for ColumnMap type rules. - - !ruby/object:Api::Type::String - name: 'failingRowsQuery' - output: true - description: | - The query to find rows that did not pass this rule. Only applies to ColumnMap and RowCondition rules. - - !ruby/object:Api::Type::String - name: 'rowCount' - output: true - description: | - The count of rows processed. - - !ruby/object:Api::Type::NestedObject - name: 'scannedData' - output: true - description: | - The data scanned for this result. - properties: - - !ruby/object:Api::Type::NestedObject - name: 'incrementalField' - description: | - The range denoted by values of an incremental field - properties: - - !ruby/object:Api::Type::String - name: 'field' - description: | - The field that contains values which monotonically increases over time (e.g. a timestamp column). - - !ruby/object:Api::Type::String - name: 'start' - description: | - Value that marks the start of the range. - - !ruby/object:Api::Type::String - name: 'end' - description: Value that marks the end of the range. - - !ruby/object:Api::Type::NestedObject - name: 'dataProfileResult' - output: true - description: | - The result of the data profile scan. - properties: - - !ruby/object:Api::Type::String - name: 'rowCount' - description: | - The count of rows scanned. - - !ruby/object:Api::Type::NestedObject - name: 'profile' - output: true - description: | - The profile information per field. - properties: - - !ruby/object:Api::Type::Array - name: 'fields' - description: | - List of fields with structural and profile information for each field. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: 'name' - description: | - The name of the field. - - !ruby/object:Api::Type::String - name: 'type' - description: | - The field data type. - - !ruby/object:Api::Type::String - name: 'mode' - description: | - The mode of the field. Possible values include: - 1. REQUIRED, if it is a required field. - 2. NULLABLE, if it is an optional field. - 3. REPEATED, if it is a repeated field. - - !ruby/object:Api::Type::NestedObject - name: 'profile' - description: | - Profile information for the corresponding field. - properties: - - !ruby/object:Api::Type::Integer - name: 'nullRatio' - output: true - description: | - Ratio of rows with null value against total scanned rows. - - !ruby/object:Api::Type::Integer - name: 'distinctRatio' - description: | - Ratio of rows with distinct values against total scanned rows. Not available for complex non-groupable field type RECORD and fields with REPEATABLE mode. - - !ruby/object:Api::Type::NestedObject - name: 'topNValues' - description: | - The list of top N non-null values and number of times they occur in the scanned data. N is 10 or equal to the number of distinct values in the field, whichever is smaller. Not available for complex non-groupable field type RECORD and fields with REPEATABLE mode. - properties: - - !ruby/object:Api::Type::String - name: 'value' - description: | - String value of a top N non-null value. - - !ruby/object:Api::Type::String - name: 'count' - description: | - Count of the corresponding value in the scanned data. - - !ruby/object:Api::Type::NestedObject - name: 'stringProfile' - output: true - description: | - String type field information. - properties: - - !ruby/object:Api::Type::String - name: 'minLength' - description: | - Minimum length of non-null values in the scanned data. - - !ruby/object:Api::Type::String - name: 'maxLength' - description: | - Maximum length of non-null values in the scanned data. - - !ruby/object:Api::Type::Integer - name: 'averageLength' - description: | - Average length of non-null values in the scanned data. - - !ruby/object:Api::Type::NestedObject - name: 'integerProfile' - output: true - description: | - Integer type field information. - properties: - - !ruby/object:Api::Type::Integer - name: 'average' - description: | - Average of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::Integer - name: 'standardDeviation' - description: | - Standard deviation of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::String - name: 'min' - description: | - Minimum of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::String - name: 'quartiles' - description: | - A quartile divides the number of data points into four parts, or quarters, of more-or-less equal size. Three main quartiles used are: The first quartile (Q1) splits off the lowest 25% of data from the highest 75%. It is also known as the lower or 25th empirical quartile, as 25% of the data is below this point. The second quartile (Q2) is the median of a data set. So, 50% of the data lies below this point. The third quartile (Q3) splits off the highest 25% of data from the lowest 75%. It is known as the upper or 75th empirical quartile, as 75% of the data lies below this point. Here, the quartiles is provided as an ordered list of quartile values for the scanned data, occurring in order Q1, median, Q3. - - !ruby/object:Api::Type::String - name: 'max' - description: | - Maximum of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::NestedObject - name: 'doubleProfile' - output: true - description: | - Double type field information. - properties: - - !ruby/object:Api::Type::Integer - name: 'average' - description: | - Average of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::Integer - name: 'standardDeviation' - description: | - Standard deviation of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::String - name: 'min' - description: | - Minimum of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::String - name: 'quartiles' - description: | - A quartile divides the number of data points into four parts, or quarters, of more-or-less equal size. Three main quartiles used are: The first quartile (Q1) splits off the lowest 25% of data from the highest 75%. It is also known as the lower or 25th empirical quartile, as 25% of the data is below this point. The second quartile (Q2) is the median of a data set. So, 50% of the data lies below this point. The third quartile (Q3) splits off the highest 25% of data from the lowest 75%. It is known as the upper or 75th empirical quartile, as 75% of the data lies below this point. Here, the quartiles is provided as an ordered list of quartile values for the scanned data, occurring in order Q1, median, Q3. - - !ruby/object:Api::Type::String - name: 'max' - description: | - Maximum of non-null values in the scanned data. NaN, if the field has a NaN. - - !ruby/object:Api::Type::NestedObject - name: 'scannedData' - output: true - description: The data scanned for this result. - properties: - - !ruby/object:Api::Type::NestedObject - name: 'incrementalField' - description: | - The range denoted by values of an incremental field - properties: - - !ruby/object:Api::Type::String - name: 'field' - description: | - The field that contains values which monotonically increases over time (e.g. a timestamp column). - - !ruby/object:Api::Type::String - name: 'start' - description: | - Value that marks the start of the range. - - !ruby/object:Api::Type::String - name: 'end' - description: Value that marks the end of the range. From f390fc92e3760d6d0ed37be6c8c48a50721c85c9 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Tue, 15 Aug 2023 12:45:38 -0700 Subject: [PATCH 007/476] Add new types KeyValueLabels and KeyValueAnnotations (#8519) * Add new type KeyValueLabels * Use KeyValueLabels in resource google_compute_address * func access_path in type * Add new type KeyValueAnnotations * Add new type KeyValueAnnotations * Fix the syntax error * Modify descriptions for labels field * Fix tests * Only read labels fingerprint when set labels * Remove version check * Fix tgc * Refactor code * Remove logger * New function properities_with_excluded * Address comments * Revert the TGC changes * Fix rake syntax errors * Fix the bug to set labels in the state * Type transform --- mmv1/api/resource.rb | 32 +++ mmv1/api/type.rb | 56 ++++ mmv1/compiler.rb | 1 + mmv1/products/bigquery/Dataset.yaml | 6 +- mmv1/products/compute/Address.yaml | 5 +- mmv1/provider/terraform.rb | 2 + .../examples/base_configs/test_file.go.erb | 2 +- .../terraform/expand_property_method.erb | 2 + .../terraform/flatten_property_method.erb | 13 + .../terraform/post_create/labels.erb | 4 + .../tests/resource_big_query_dataset_test.go | 149 ++++++++-- .../tests/resource_compute_address_test.go | 112 -------- .../resource_compute_address_test.go.erb | 256 ++++++++++++++++++ 13 files changed, 503 insertions(+), 137 deletions(-) delete mode 100644 mmv1/third_party/terraform/tests/resource_compute_address_test.go create mode 100644 mmv1/third_party/terraform/tests/resource_compute_address_test.go.erb diff --git a/mmv1/api/resource.rb b/mmv1/api/resource.rb index 799420f2dd80..42766e6c9afc 100644 --- a/mmv1/api/resource.rb +++ b/mmv1/api/resource.rb @@ -338,6 +338,10 @@ def all_properties ((@properties || []) + (@parameters || [])) end + def properties_with_excluded + @properties || [] + end + def properties (@properties || []).reject(&:exclude) end @@ -435,6 +439,34 @@ def decoder? !@transport&.decoder.nil? end + def add_labels_related_fields(props) + props.each do |p| + if p.is_a? Api::Type::KeyValueLabels + props << build_effective_labels_field('labels', p.field_min_version) + elsif p.is_a? Api::Type::KeyValueAnnotations + props << build_effective_labels_field('annotations', p.field_min_version) + elsif (p.is_a? Api::Type::NestedObject) && !p.all_properties.nil? + p.properties = add_labels_related_fields(p.all_properties) + end + end + props + end + + def build_effective_labels_field(name, min_version) + description = "All of #{name} (key/value pairs)\ + present on the resource in GCP, including the #{name} configured through Terraform,\ + other clients and services." + + Api::Type::KeyValuePairs.new( + name: "effective_#{name}", + output: true, + api_name: name, + description:, + min_version:, + ignore_write: true + ) + end + # ==================== # Version-related methods # ==================== diff --git a/mmv1/api/type.rb b/mmv1/api/type.rb index 2d0900b1fd7d..d8b505199993 100644 --- a/mmv1/api/type.rb +++ b/mmv1/api/type.rb @@ -266,6 +266,14 @@ def lineage "#{__parent.lineage}.#{name&.underscore}" end + # Prints the access path of the field in the configration eg: metadata.0.labels + # The only intended purpose is to get the value of the labes field by calling d.Get(). + def terraform_lineage + return name&.underscore if __parent.nil? + + "#{__parent.terraform_lineage}.0.#{name&.underscore}" + end + def to_json(opts = nil) # ignore fields that will contain references to parent resources and # those which will be added later @@ -728,6 +736,8 @@ def properties @properties.reject(&:exclude) end + attr_writer :properties + def nested_properties properties end @@ -755,6 +765,52 @@ def exclude_if_not_in_version!(version) # simpler property to generate and means we can avoid conditional logic # in Map. class KeyValuePairs < Composite + # Ignore writing the "effective_labels" and "effective_annotations" fields to API. + attr_reader :ignore_write + + def initialize(name: nil, output: nil, api_name: nil, description: nil, min_version: nil, + ignore_write: nil) + super() + + @name = name + @output = output + @api_name = api_name + @description = description + @min_version = min_version + @ignore_write = ignore_write + end + + def validate + super + check :ignore_write, type: :boolean, default: false + end + + def field_min_version + @min_version + end + end + + # An array of string -> string key -> value pairs used specifically for the "labels" field. + # The field name with this type should be "labels" literally. + class KeyValueLabels < KeyValuePairs + def validate + super + return unless @name != 'labels' + + raise "The field #{name} has the type KeyValueLabels, but the field name is not 'labels'!" + end + end + + # An array of string -> string key -> value pairs used specifically for the "annotations" field. + # The field name with this type should be "annotations" literally. + class KeyValueAnnotations < KeyValuePairs + def validate + super + return unless @name != 'annotations' + + raise "The field #{name} has the type KeyValueAnnotations,\ + but the field name is not 'annotations'!" + end end # Map from string keys -> nested object entries diff --git a/mmv1/compiler.rb b/mmv1/compiler.rb index 00a414c0552a..0ca7dc22b610 100755 --- a/mmv1/compiler.rb +++ b/mmv1/compiler.rb @@ -223,6 +223,7 @@ end res_yaml = File.read(file_path) resource = Api::Compiler.new(res_yaml).run + resource.properties = resource.add_labels_related_fields(resource.properties_with_excluded) resource.validate resources.push(resource) end diff --git a/mmv1/products/bigquery/Dataset.yaml b/mmv1/products/bigquery/Dataset.yaml index 7cd95a4eb7f1..2fb36dfc2c06 100644 --- a/mmv1/products/bigquery/Dataset.yaml +++ b/mmv1/products/bigquery/Dataset.yaml @@ -290,12 +290,14 @@ properties: name: 'friendlyName' description: A descriptive name for the dataset send_empty_value: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | The labels associated with this dataset. You can use these to organize and group your datasets - default_from_api: true + + **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. - !ruby/object:Api::Type::Integer name: 'lastModifiedTime' description: | diff --git a/mmv1/products/compute/Address.yaml b/mmv1/products/compute/Address.yaml index 59a26cd3b1bd..cd80696c04ba 100644 --- a/mmv1/products/compute/Address.yaml +++ b/mmv1/products/compute/Address.yaml @@ -194,10 +194,13 @@ properties: description: 'The URLs of the resources that are using this address.' item_type: Api::Type::String output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Labels to apply to this address. A list of key->value pairs. + + **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. update_verb: :POST update_url: 'projects/{{project}}/regions/{{region}}/addresses/{{name}}/setLabels' min_version: beta diff --git a/mmv1/provider/terraform.rb b/mmv1/provider/terraform.rb index 220b52b62e23..753f1479f23c 100644 --- a/mmv1/provider/terraform.rb +++ b/mmv1/provider/terraform.rb @@ -91,6 +91,8 @@ def tf_types Api::Type::NestedObject => 'schema.TypeList', Api::Type::Array => 'schema.TypeList', Api::Type::KeyValuePairs => 'schema.TypeMap', + Api::Type::KeyValueLabels => 'schema.TypeMap', + Api::Type::KeyValueAnnotations => 'schema.TypeMap', Api::Type::Map => 'schema.TypeSet', Api::Type::Fingerprint => 'schema.TypeString' } diff --git a/mmv1/templates/terraform/examples/base_configs/test_file.go.erb b/mmv1/templates/terraform/examples/base_configs/test_file.go.erb index 967d78cb63c7..40eafa9afadc 100644 --- a/mmv1/templates/terraform/examples/base_configs/test_file.go.erb +++ b/mmv1/templates/terraform/examples/base_configs/test_file.go.erb @@ -44,7 +44,7 @@ object.examples test_slug = "#{resource_name}_#{example.name.camelize(:lower)}Example" ignore_read = object.all_user_properties - .select{|p| p.url_param_only || p.ignore_read || p.is_a?(Api::Type::ResourceRef) } + .select{|p| p.url_param_only || p.ignore_read || p.is_a?(Api::Type::ResourceRef) || p.is_a?(Api::Type::KeyValueLabels || p.is_a?(Api::Type::KeyValueAnnotations))} .map { |p| p.name.underscore } .concat(example.ignore_read_extra) diff --git a/mmv1/templates/terraform/expand_property_method.erb b/mmv1/templates/terraform/expand_property_method.erb index d3a034e84ca2..880242320bd5 100644 --- a/mmv1/templates/terraform/expand_property_method.erb +++ b/mmv1/templates/terraform/expand_property_method.erb @@ -130,6 +130,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d t transformed := make(map[string]interface{}) <% property.nested_properties.each do |prop| -%> +<% next if prop.is_a?(Api::Type::KeyValuePairs) && prop.ignore_write -%> transformed<%= titlelize_property(prop) -%>, err := expand<%= prefix -%><%= titlelize_property(property) -%><%= titlelize_property(prop) -%>(original["<%= prop.name.underscore -%>"], d, config) if err != nil { return nil, err @@ -175,6 +176,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d t <% if !property.nested_properties.nil? -%> <% property.nested_properties.each do |prop| -%> +<% next if prop.is_a?(Api::Type::KeyValuePairs) && prop.ignore_write -%> <%# Map is a map from {key -> object} in the API, but Terraform can't represent that so we treat the key as a property of the object in Terraform schema. %> <%= lines(build_expand_method(prefix + titlelize_property(property), prop, object, pwd), 1) -%> diff --git a/mmv1/templates/terraform/flatten_property_method.erb b/mmv1/templates/terraform/flatten_property_method.erb index ed6eda44afcc..5f8fdb875590 100644 --- a/mmv1/templates/terraform/flatten_property_method.erb +++ b/mmv1/templates/terraform/flatten_property_method.erb @@ -93,6 +93,19 @@ func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d <% end -%> }) } + return transformed +<% elsif (property.is_a?(Api::Type::KeyValueLabels)) || (property.is_a?(Api::Type::KeyValueAnnotations)) -%> + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("<%= property.terraform_lineage -%>"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + return transformed <% elsif property.is_a?(Api::Type::Integer) -%> // Handles the string fixed64 format diff --git a/mmv1/templates/terraform/post_create/labels.erb b/mmv1/templates/terraform/post_create/labels.erb index 83c6dcea64a9..e725830eaabd 100644 --- a/mmv1/templates/terraform/post_create/labels.erb +++ b/mmv1/templates/terraform/post_create/labels.erb @@ -46,5 +46,9 @@ if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v return err } + // Set back the labels field, as it is needed to decide the value of "labels" in the state in the read function. + if err := d.Set("labels", v); err != nil { + return fmt.Errorf("Error setting back labels: %s", err) + } } <% end -%> diff --git a/mmv1/third_party/terraform/tests/resource_big_query_dataset_test.go b/mmv1/third_party/terraform/tests/resource_big_query_dataset_test.go index 0c3ed02f1af1..c31e9b00b294 100644 --- a/mmv1/third_party/terraform/tests/resource_big_query_dataset_test.go +++ b/mmv1/third_party/terraform/tests/resource_big_query_dataset_test.go @@ -22,7 +22,11 @@ func TestAccBigQueryDataset_basic(t *testing.T) { CheckDestroy: testAccCheckBigQueryDatasetDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccBigQueryDataset(datasetID), + Config: testAccBigQueryDataset_withoutLabels(datasetID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_bigquery_dataset.test", "labels.%"), + resource.TestCheckNoResourceAttr("google_bigquery_dataset.test", "effective_labels.%"), + ), }, { ResourceName: "google_bigquery_dataset.test", @@ -30,16 +34,59 @@ func TestAccBigQueryDataset_basic(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccBigQueryDatasetUpdated(datasetID), + Config: testAccBigQueryDataset(datasetID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.%", "2"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.default_table_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.%", "2"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.env", "foo"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.default_table_expiration_ms", "3600000"), + ), }, { ResourceName: "google_bigquery_dataset.test", ImportState: true, ImportStateVerify: true, + // The labels field in the state is decided by the configuration. + // During importing, the configuration is unavailable, so the labels field in the state after importing is empty. + ImportStateVerifyIgnore: []string{"labels"}, + }, + { + Config: testAccBigQueryDatasetUpdated(datasetID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.%", "2"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.env", "bar"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.default_table_expiration_ms", "7200000"), + + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.%", "2"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.env", "bar"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.default_table_expiration_ms", "7200000"), + ), + }, + { + ResourceName: "google_bigquery_dataset.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, { Config: testAccBigQueryDatasetUpdated2(datasetID), }, + { + ResourceName: "google_bigquery_dataset.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, + }, + { + Config: testAccBigQueryDataset_withoutLabels(datasetID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_bigquery_dataset.test", "labels.%"), + resource.TestCheckNoResourceAttr("google_bigquery_dataset.test", "effective_labels.%"), + ), + }, { ResourceName: "google_bigquery_dataset.test", ImportState: true, @@ -49,6 +96,47 @@ func TestAccBigQueryDataset_basic(t *testing.T) { }) } +func TestAccBigQueryDataset_withProvider5(t *testing.T) { + acctest.SkipIfVcr(t) + t.Parallel() + + datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + oldVersion := map[string]resource.ExternalProvider{ + "google": { + VersionConstraint: "4.75.0", // a version that doesn't separate user defined labels and system labels + Source: "registry.terraform.io/hashicorp/google", + }, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + CheckDestroy: testAccCheckBigQueryDatasetDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryDataset_withoutLabels(datasetID), + ExternalProviders: oldVersion, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_bigquery_dataset.test", "labels.%"), + resource.TestCheckNoResourceAttr("google_bigquery_dataset.test", "effective_labels.%"), + ), + }, + { + Config: testAccBigQueryDataset(datasetID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.%", "2"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "labels.default_table_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.%", "2"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.env", "foo"), + resource.TestCheckResourceAttr("google_bigquery_dataset.test", "effective_labels.default_table_expiration_ms", "3600000"), + ), + }, + }, + }) +} + func TestAccBigQueryDataset_datasetWithContents(t *testing.T) { t.Parallel() @@ -68,7 +156,7 @@ func TestAccBigQueryDataset_datasetWithContents(t *testing.T) { ResourceName: "google_bigquery_dataset.contents_test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"delete_contents_on_destroy"}, + ImportStateVerifyIgnore: []string{"delete_contents_on_destroy", "labels"}, }, }, }) @@ -90,33 +178,37 @@ func TestAccBigQueryDataset_access(t *testing.T) { Config: testAccBigQueryDatasetWithOneAccess(datasetID), }, { - ResourceName: "google_bigquery_dataset.access_test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_bigquery_dataset.access_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, { Config: testAccBigQueryDatasetWithTwoAccess(datasetID), }, { - ResourceName: "google_bigquery_dataset.access_test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_bigquery_dataset.access_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, { Config: testAccBigQueryDatasetWithOneAccess(datasetID), }, { - ResourceName: "google_bigquery_dataset.access_test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_bigquery_dataset.access_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, { Config: testAccBigQueryDatasetWithViewAccess(datasetID, otherDatasetID, otherTableID), }, { - ResourceName: "google_bigquery_dataset.access_test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_bigquery_dataset.access_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -136,9 +228,10 @@ func TestAccBigQueryDataset_regionalLocation(t *testing.T) { Config: testAccBigQueryRegionalDataset(datasetID1, "asia-south1"), }, { - ResourceName: "google_bigquery_dataset.test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_bigquery_dataset.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -181,9 +274,10 @@ func TestAccBigQueryDataset_storageBillModel(t *testing.T) { Config: testAccBigQueryDatasetStorageBillingModel(datasetID), }, { - ResourceName: "google_bigquery_dataset.test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_bigquery_dataset.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -208,6 +302,19 @@ func testAccAddTable(t *testing.T, datasetID string, tableID string) resource.Te } } +func testAccBigQueryDataset_withoutLabels(datasetID string) string { + return fmt.Sprintf(` +resource "google_bigquery_dataset" "test" { + dataset_id = "%s" + friendly_name = "foo" + description = "This is a foo description" + location = "EU" + default_partition_expiration_ms = 3600000 + default_table_expiration_ms = 3600000 +} +`, datasetID) +} + func testAccBigQueryDataset(datasetID string) string { return fmt.Sprintf(` resource "google_bigquery_dataset" "test" { diff --git a/mmv1/third_party/terraform/tests/resource_compute_address_test.go b/mmv1/third_party/terraform/tests/resource_compute_address_test.go deleted file mode 100644 index afab1990ba55..000000000000 --- a/mmv1/third_party/terraform/tests/resource_compute_address_test.go +++ /dev/null @@ -1,112 +0,0 @@ -package google - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-provider-google/google/acctest" -) - -func TestAccComputeAddress_networkTier(t *testing.T) { - t.Parallel() - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckComputeAddressDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), - }, - { - ResourceName: "google_compute_address.foobar", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccComputeAddress_internal(t *testing.T) { - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckComputeAddressDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccComputeAddress_internal(acctest.RandString(t, 10)), - }, - { - ResourceName: "google_compute_address.internal", - ImportState: true, - ImportStateVerify: true, - }, - - { - ResourceName: "google_compute_address.internal_with_subnet", - ImportState: true, - ImportStateVerify: true, - }, - - { - ResourceName: "google_compute_address.internal_with_subnet_and_address", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccComputeAddress_internal(i string) string { - return fmt.Sprintf(` -resource "google_compute_address" "internal" { - name = "tf-test-address-internal-%s" - address_type = "INTERNAL" - region = "us-east1" -} - -resource "google_compute_network" "default" { - name = "tf-test-network-test-%s" -} - -resource "google_compute_subnetwork" "foo" { - name = "subnetwork-test-%s" - ip_cidr_range = "10.0.0.0/16" - region = "us-east1" - network = google_compute_network.default.self_link -} - -resource "google_compute_address" "internal_with_subnet" { - name = "tf-test-address-internal-with-subnet-%s" - subnetwork = google_compute_subnetwork.foo.self_link - address_type = "INTERNAL" - region = "us-east1" -} - -// We can't test the address alone, because we don't know what IP range the -// default subnetwork uses. -resource "google_compute_address" "internal_with_subnet_and_address" { - name = "tf-test-address-internal-with-subnet-and-address-%s" - subnetwork = google_compute_subnetwork.foo.self_link - address_type = "INTERNAL" - address = "10.0.42.42" - region = "us-east1" -} -`, - i, // google_compute_address.internal name - i, // google_compute_network.default name - i, // google_compute_subnetwork.foo name - i, // google_compute_address.internal_with_subnet_name - i, // google_compute_address.internal_with_subnet_and_address name - ) -} - -func testAccComputeAddress_networkTier(i string) string { - return fmt.Sprintf(` -resource "google_compute_address" "foobar" { - name = "tf-test-address-%s" - network_tier = "STANDARD" -} -`, i) -} diff --git a/mmv1/third_party/terraform/tests/resource_compute_address_test.go.erb b/mmv1/third_party/terraform/tests/resource_compute_address_test.go.erb new file mode 100644 index 000000000000..11987ad189ab --- /dev/null +++ b/mmv1/third_party/terraform/tests/resource_compute_address_test.go.erb @@ -0,0 +1,256 @@ +<% autogen_exception -%> + +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccComputeAddress_networkTier(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeAddressDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "labels.%"), + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "effective_labels.%"), + ), + }, + }, + }) +} + +func TestAccComputeAddress_internal(t *testing.T) { + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeAddressDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeAddress_internal(acctest.RandString(t, 10)), + }, + { + ResourceName: "google_compute_address.internal", + ImportState: true, + ImportStateVerify: true, + }, + + { + ResourceName: "google_compute_address.internal_with_subnet", + ImportState: true, + ImportStateVerify: true, + }, + + { + ResourceName: "google_compute_address.internal_with_subnet_and_address", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +<% unless version == "ga" -%> +func TestAccComputeAddress_networkTier_withLabels(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeAddressDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "labels.%"), + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "effective_labels.%"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeAddress_networkTier_withLabels(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.default_expiration_ms", "3600000"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + // The labels field in the state is decided by the configuration. + // During importing, the configuration is unavailable, so the labels field in the state after importing is empty. + ImportStateVerifyIgnore: []string{"labels"}, + }, + { + Config: testAccComputeAddress_networkTier_withLabelsUpdate(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.env", "bar"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "7200000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.env", "bar"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.default_expiration_ms", "7200000"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, + }, + { + Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "labels.%"), + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "effective_labels.%"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeAddress_networkTier_withProvider5(t *testing.T) { + acctest.SkipIfVcr(t) + t.Parallel() + + oldVersion := map[string]resource.ExternalProvider{ + "google": { + VersionConstraint: "4.75.0", // a version that doesn't separate user defined labels and system labels + Source: "registry.terraform.io/hashicorp/google", + }, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + Steps: []resource.TestStep{ + { + Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), + ExternalProviders: oldVersion, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "labels.%"), + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "effective_labels.%"), + ), + }, + { + Config: testAccComputeAddress_networkTier_withLabels(acctest.RandString(t, 10)), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.default_expiration_ms", "3600000"), + ), + }, + }, + }) +} + +func testAccComputeAddress_networkTier_withLabels(i string) string { + return fmt.Sprintf(` +resource "google_compute_address" "foobar" { + name = "tf-test-address-%s" + network_tier = "STANDARD" + + labels = { + env = "foo" + default_expiration_ms = 3600000 + } +} +`, i) +} + +func testAccComputeAddress_networkTier_withLabelsUpdate(i string) string { + return fmt.Sprintf(` +resource "google_compute_address" "foobar" { + name = "tf-test-address-%s" + network_tier = "STANDARD" + + labels = { + env = "bar" + default_expiration_ms = 7200000 + } +} +`, i) +} +<% end -%> + +func testAccComputeAddress_internal(i string) string { + return fmt.Sprintf(` +resource "google_compute_address" "internal" { + name = "tf-test-address-internal-%s" + address_type = "INTERNAL" + region = "us-east1" +} + +resource "google_compute_network" "default" { + name = "tf-test-network-test-%s" +} + +resource "google_compute_subnetwork" "foo" { + name = "subnetwork-test-%s" + ip_cidr_range = "10.0.0.0/16" + region = "us-east1" + network = google_compute_network.default.self_link +} + +resource "google_compute_address" "internal_with_subnet" { + name = "tf-test-address-internal-with-subnet-%s" + subnetwork = google_compute_subnetwork.foo.self_link + address_type = "INTERNAL" + region = "us-east1" +} + +// We can't test the address alone, because we don't know what IP range the +// default subnetwork uses. +resource "google_compute_address" "internal_with_subnet_and_address" { + name = "tf-test-address-internal-with-subnet-and-address-%s" + subnetwork = google_compute_subnetwork.foo.self_link + address_type = "INTERNAL" + address = "10.0.42.42" + region = "us-east1" +} +`, + i, // google_compute_address.internal name + i, // google_compute_network.default name + i, // google_compute_subnetwork.foo name + i, // google_compute_address.internal_with_subnet_name + i, // google_compute_address.internal_with_subnet_and_address name + ) +} + +func testAccComputeAddress_networkTier(i string) string { + return fmt.Sprintf(` +resource "google_compute_address" "foobar" { + name = "tf-test-address-%s" + network_tier = "STANDARD" +} +`, i) +} \ No newline at end of file From 1ac6933c3664f1afb8a4c5b4739fe09a416e318f Mon Sep 17 00:00:00 2001 From: wj-chen Date: Tue, 15 Aug 2023 14:35:18 -0700 Subject: [PATCH 008/476] make routineType required in the BigQuery Routine resource (#8573) --- mmv1/products/bigquery/Routine.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/mmv1/products/bigquery/Routine.yaml b/mmv1/products/bigquery/Routine.yaml index 054100c13ee9..7e57fd7dd1fb 100644 --- a/mmv1/products/bigquery/Routine.yaml +++ b/mmv1/products/bigquery/Routine.yaml @@ -76,6 +76,7 @@ properties: - !ruby/object:Api::Type::Enum name: 'routineType' immutable: true + required: true description: The type of routine. values: - :SCALAR_FUNCTION From 764e379a95749de51d9b23af52ff706338ae232d Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Tue, 15 Aug 2023 14:48:09 -0700 Subject: [PATCH 009/476] Add default value to metric.filter in the resource google_compute_autoscaler (#8327) --- mmv1/products/compute/Autoscaler.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/mmv1/products/compute/Autoscaler.yaml b/mmv1/products/compute/Autoscaler.yaml index e10212ef636b..8c66621727e9 100644 --- a/mmv1/products/compute/Autoscaler.yaml +++ b/mmv1/products/compute/Autoscaler.yaml @@ -367,6 +367,7 @@ properties: TimeSeries are returned upon the query execution, the autoscaler will sum their respective values to obtain its scaling value. min_version: beta + default_value: 'resource.type = gce_instance' - !ruby/object:Api::Type::NestedObject name: 'loadBalancingUtilization' description: | From 5de4e819d97f33c08b15a6329d82c9dbd290eb77 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Tue, 15 Aug 2023 14:59:49 -0700 Subject: [PATCH 010/476] Modify labels fields for DCL resources (#8563) * Modify labels fields * effective_labels filed is not optional * Add tests for labels * Append notes for lables description * Fix the notes --- ...esource_cloudbuild_worker_pool_test.go.erb | 6 +++ ...rce_dataproc_workflow_template_test.go.erb | 9 ++++ .../samples/asset/basic_asset.tf.tmpl | 6 +++ tpgtools/property.go | 39 ++++++++++++++++ tpgtools/resource.go | 44 +++++++++++++++++++ tpgtools/templates/resource.go.tmpl | 34 ++++++++++++++ 6 files changed, 138 insertions(+) diff --git a/mmv1/third_party/terraform/tests/resource_cloudbuild_worker_pool_test.go.erb b/mmv1/third_party/terraform/tests/resource_cloudbuild_worker_pool_test.go.erb index 8dc25191686e..acfef3e1978b 100644 --- a/mmv1/third_party/terraform/tests/resource_cloudbuild_worker_pool_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_cloudbuild_worker_pool_test.go.erb @@ -41,6 +41,7 @@ func TestAccCloudbuildWorkerPool_basic(t *testing.T) { { ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, ResourceName: "google_cloudbuild_worker_pool.pool", }, { @@ -79,6 +80,11 @@ resource "google_cloudbuild_worker_pool" "pool" { machine_type = "e2-standard-4" no_external_ip = false } + + annotations = { + env = "foo" + default_expiration_ms = 3600000 + } } `, context) } diff --git a/mmv1/third_party/terraform/tests/resource_dataproc_workflow_template_test.go.erb b/mmv1/third_party/terraform/tests/resource_dataproc_workflow_template_test.go.erb index a277266a01a4..495e7d8e8f73 100644 --- a/mmv1/third_party/terraform/tests/resource_dataproc_workflow_template_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_dataproc_workflow_template_test.go.erb @@ -37,6 +37,10 @@ func TestAccDataprocWorkflowTemplate_basic(t *testing.T) { { ImportState: true, ImportStateVerify: true, + // The "labels" field in the state are decided by the configuration. + // During importing, as the configuration is unavailableafter, the "labels" field in the state will be empty. + // So add the "labels" to the ImportStateVerifyIgnore list. + ImportStateVerifyIgnore: []string{"labels"}, ResourceName: "google_dataproc_workflow_template.template", }, }, @@ -124,6 +128,11 @@ resource "google_dataproc_workflow_template" "template" { query_file_uri = "someuri" } } + + labels = { + env = "foo" + somekey = "somevalue" + } } `, context) } diff --git a/tpgtools/overrides/dataplex/samples/asset/basic_asset.tf.tmpl b/tpgtools/overrides/dataplex/samples/asset/basic_asset.tf.tmpl index 07c9141bb937..d3f18d1990dd 100644 --- a/tpgtools/overrides/dataplex/samples/asset/basic_asset.tf.tmpl +++ b/tpgtools/overrides/dataplex/samples/asset/basic_asset.tf.tmpl @@ -52,6 +52,12 @@ resource "google_dataplex_asset" "primary" { name = "projects/{{project}}/buckets/{{bucket}}" type = "STORAGE_BUCKET" } + + labels = { + env = "foo" + my-asset = "exists" + } + project = "{{project}}" depends_on = [ diff --git a/tpgtools/property.go b/tpgtools/property.go index 0ee26f2af299..0292c3124857 100644 --- a/tpgtools/property.go +++ b/tpgtools/property.go @@ -311,6 +311,10 @@ func (p Property) DefaultStateSetter() string { case SchemaTypeFloat: fallthrough case SchemaTypeMap: + if p.IsResourceLabels() || p.IsResourceAnnotations() { + return fmt.Sprintf("d.Set(%q, flatten%s%s(res.%s, d))", p.Name(), p.resource.PathType(), p.PackagePath(), p.PackageName) + } + return fmt.Sprintf("d.Set(%q, res.%s)", p.Name(), p.PackageName) case SchemaTypeList, SchemaTypeSet: if p.typ.Items != nil && ((p.typ.Items.Type == "string" && len(p.typ.Items.Enum) == 0) || p.typ.Items.Type == "integer") { @@ -440,6 +444,14 @@ func (p Property) Objects() (props []Property) { return props } +func (p Property) IsResourceLabels() bool { + return p.Name() == "labels" && p.parent == nil +} + +func (p Property) IsResourceAnnotations() bool { + return p.Name() == "annotations" && p.parent == nil +} + // collapsedProperties returns the input list of properties with nested objects collapsed if needed. func collapsedProperties(props []Property) (collapsed []Property) { for _, v := range props { @@ -878,6 +890,16 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher resource.ReusedTypes = resource.RegisterReusedType(p) } + // Add the "effective_labels" property when the current property is top level "labels" or + // add the "effective_annotations" property when the current property is top level "annotations" + + if p.IsResourceLabels() || p.IsResourceAnnotations() { + note := "**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." + p.Description = fmt.Sprintf("%s\n\n%s", p.Description, note) + props = append(props, build_effective_labels_field(p, resource, parent)) + } + props = append(props, p) } @@ -901,3 +923,20 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher return props, nil } + +func build_effective_labels_field(p Property, resource *Resource, parent *Property) Property { + title := fmt.Sprintf("effective_%s", p.title) + description := fmt.Sprintf("All of %s (key/value pairs) present on the resource in GCP, including the %s configured through Terraform, other clients and services.", p.title, p.title) + stateSetter := fmt.Sprintf("d.Set(%q, res.%s)", title, p.PackageName) + + return Property{ + title: title, + Type: p.Type, + Description: description, + resource: resource, + parent: parent, + Optional: false, + Computed: true, + StateSetter: &stateSetter, + } +} diff --git a/tpgtools/resource.go b/tpgtools/resource.go index b65c2061f9f9..1e6f6e7a1498 100644 --- a/tpgtools/resource.go +++ b/tpgtools/resource.go @@ -381,6 +381,26 @@ func (r Resource) IDFunction() string { return "tpgresource.ReplaceVarsForId" } +// Check if the resource has the lables field for the resource +func (r Resource) HasLabels() bool { + for _, p := range r.Properties { + if p.IsResourceLabels() { + return true + } + } + return false +} + +// Check if the resource has the annotations field for the resource +func (r Resource) HasAnnotations() bool { + for _, p := range r.Properties { + if p.IsResourceAnnotations() { + return true + } + } + return false +} + // ResourceInput is a Resource along with additional generation metadata. type ResourceInput struct { Resource @@ -810,6 +830,18 @@ func (r *Resource) loadHandWrittenSamples() []Sample { sample.Name = &sampleName } sample.TestSlug = RenderedString(snakeToTitleCase(miscellaneousNameSnakeCase(sampleName)).titlecase() + "HandWritten") + + // The "labels" and "annotations" fields in the state are decided by the configuration. + // During importing, as the configuration is unavailableafter, the "labels" and "annotations" fields in the state will be empty. + // So add the "labels" and the "annotations" fields to the ImportStateVerifyIgnore list. + if r.HasLabels() { + sample.IgnoreRead = append(sample.IgnoreRead, "labels") + } + + if r.HasAnnotations() { + sample.IgnoreRead = append(sample.IgnoreRead, "annotations") + } + samples = append(samples, sample) } @@ -896,6 +928,18 @@ func (r *Resource) loadDCLSamples() []Sample { } sample.DependencyList = dependencies sample.TestSlug = RenderedString(sampleNameToTitleCase(*sample.Name).titlecase()) + + // The "labels" and "annotations" fields in the state are decided by the configuration. + // During importing, as the configuration is unavailableafter, the "labels" and "annotations" fields in the state will be empty. + // So add the "labels" and the "annotations" fields to the ImportStateVerifyIgnore list. + if r.HasLabels() { + sample.IgnoreRead = append(sample.IgnoreRead, "labels") + } + + if r.HasAnnotations() { + sample.IgnoreRead = append(sample.IgnoreRead, "annotations") + } + samples = append(samples, sample) } diff --git a/tpgtools/templates/resource.go.tmpl b/tpgtools/templates/resource.go.tmpl index 532dd4c4c75b..a3f10f2db10b 100644 --- a/tpgtools/templates/resource.go.tmpl +++ b/tpgtools/templates/resource.go.tmpl @@ -714,6 +714,40 @@ func flatten{{$.PathType}}{{$v.PackagePath}}(obj *{{$.Package}}.{{$v.ObjectType} } {{ end -}} +{{ if $.HasLabels }} +func flatten{{$.PathType}}Labels(v map[string]string, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + + transformed := make(map[string]interface{}) + if l, ok := d.Get("labels").(map[string]interface{}); ok { + for k, _ := range l { + transformed[k] = l[k] + } + } + + return transformed +} +{{ end }} + +{{ if $.HasAnnotations }} +func flatten{{$.PathType}}Annotations(v map[string]string, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + + transformed := make(map[string]interface{}) + if l, ok := d.Get("annotations").(map[string]interface{}); ok { + for k, _ := range l { + transformed[k] = l[k] + } + } + + return transformed +} +{{ end }} + {{ range $v := .EnumArrays -}} func flatten{{$.PathType}}{{$v.PackagePath}}Array(obj []{{$.Package}}.{{$v.ObjectType}}Enum) interface{} { if obj == nil { From f94c19dbf29fa8e1c4a50a69668c02d9e558ed74 Mon Sep 17 00:00:00 2001 From: gfxcc Date: Wed, 16 Aug 2023 14:27:38 -0700 Subject: [PATCH 011/476] remove deprecated fields (#8531) --- mmv1/products/privateca/Certificate.yaml | 132 ----------------------- 1 file changed, 132 deletions(-) diff --git a/mmv1/products/privateca/Certificate.yaml b/mmv1/products/privateca/Certificate.yaml index 2d8b63d41544..67f04352cd18 100644 --- a/mmv1/products/privateca/Certificate.yaml +++ b/mmv1/products/privateca/Certificate.yaml @@ -544,131 +544,6 @@ properties: leading period (like `.example.com`) output: true item_type: Api::Type::String - - !ruby/object:Api::Type::NestedObject - name: 'configValues' - deprecation_message: Deprecated in favor of `x509_description`. - output: true - description: | - Describes some of the technical fields in a certificate. - properties: - - !ruby/object:Api::Type::NestedObject - name: 'keyUsage' - output: true - description: | - Indicates the intended use for keys that correspond to a certificate. - properties: - - !ruby/object:Api::Type::NestedObject - name: 'baseKeyUsage' - output: true - description: | - Describes high-level ways in which a key may be used. - properties: - - !ruby/object:Api::Type::NestedObject - name: 'keyUsageOptions' - output: true - description: | - Describes high-level ways in which a key may be used. - properties: - - !ruby/object:Api::Type::Boolean - name: 'digitalSignature' - output: true - description: | - The key may be used for digital signatures. - - !ruby/object:Api::Type::Boolean - name: 'contentCommitment' - output: true - description: | - The key may be used for cryptographic commitments. Note that this may also be referred to as "non-repudiation". - - !ruby/object:Api::Type::Boolean - name: 'keyEncipherment' - output: true - description: | - The key may be used to encipher other keys. - - !ruby/object:Api::Type::Boolean - name: 'dataEncipherment' - output: true - description: | - The key may be used to encipher data. - - !ruby/object:Api::Type::Boolean - name: 'keyAgreement' - output: true - description: | - The key may be used in a key agreement protocol. - - !ruby/object:Api::Type::Boolean - name: 'certSign' - output: true - description: | - The key may be used to sign certificates. - - !ruby/object:Api::Type::Boolean - name: 'crlSign' - output: true - description: | - The key may be used sign certificate revocation lists. - - !ruby/object:Api::Type::Boolean - name: 'encipherOnly' - output: true - description: | - The key may be used to encipher only. - - !ruby/object:Api::Type::Boolean - name: 'decipherOnly' - output: true - description: | - The key may be used to decipher only. - - !ruby/object:Api::Type::NestedObject - name: 'extendedKeyUsage' - output: true - description: | - Describes high-level ways in which a key may be used. - properties: - - !ruby/object:Api::Type::Boolean - name: 'serverAuth' - output: true - description: | - Corresponds to OID 1.3.6.1.5.5.7.3.1. Officially described as "TLS WWW server authentication", though regularly used for non-WWW TLS. - - !ruby/object:Api::Type::Boolean - name: 'clientAuth' - output: true - description: | - Corresponds to OID 1.3.6.1.5.5.7.3.2. Officially described as "TLS WWW client authentication", though regularly used for non-WWW TLS. - - !ruby/object:Api::Type::Boolean - name: 'codeSigning' - output: true - description: | - Corresponds to OID 1.3.6.1.5.5.7.3.3. Officially described as "Signing of downloadable executable code client authentication". - - !ruby/object:Api::Type::Boolean - name: 'emailProtection' - output: true - description: | - Corresponds to OID 1.3.6.1.5.5.7.3.4. Officially described as "Email protection". - - !ruby/object:Api::Type::Boolean - name: 'timeStamping' - output: true - description: | - Corresponds to OID 1.3.6.1.5.5.7.3.8. Officially described as "Binding the hash of an object to a time". - - !ruby/object:Api::Type::Boolean - name: 'ocspSigning' - output: true - description: | - Corresponds to OID 1.3.6.1.5.5.7.3.9. Officially described as "Signing OCSP responses". - - !ruby/object:Api::Type::Array - name: 'unknownExtendedKeyUsages' - output: true - description: | - An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::NestedObject - name: 'obectId' - output: true - description: | - Required. Describes how some of the technical fields in a certificate should be populated. - properties: - - !ruby/object:Api::Type::Array - name: 'objectIdPath' - output: true - item_type: Api::Type::Integer - description: | - An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages. - !ruby/object:Api::Type::NestedObject name: 'publicKey' output: true @@ -739,13 +614,6 @@ properties: description: | The chain that may be used to verify the X.509 certificate. Expected to be in issuer-to-root order according to RFC 5246. item_type: Api::Type::String - - !ruby/object:Api::Type::Array - name: 'pemCertificates' - deprecation_message: Deprecated in favor of `pem_certificate_chain`. - output: true - description: | - Required. Expected to be in leaf-to-root order according to RFC 5246. - item_type: Api::Type::String - !ruby/object:Api::Type::Time name: 'createTime' description: | From 74d45a2e896ff15481d548da5fb0ad8d9af5c153 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Thu, 17 Aug 2023 12:40:25 -0700 Subject: [PATCH 012/476] Modify labels field for some handwritten resources (#8579) * Modify lables field * Fix description * Fix tests * Ignore labels for import state verify * Ignore labels for import state verify --- .../bigquery/resource_bigquery_table.go | 19 +++++++++++++++---- .../bigtable/resource_bigtable_instance.go | 19 ++++++++++++++++--- .../resource_cloudfunctions_function.go | 17 +++++++++++++++-- .../resource_composer_environment.go.erb | 17 +++++++++++++++-- .../compute/resource_compute_instance.go.erb | 18 ++++++++++++++++-- .../resource_compute_instance_template.go.erb | 17 +++++++++++++++-- .../dataproc/resource_dataproc_job.go.erb | 17 +++++++++++++++-- .../resource_google_project.go | 19 ++++++++++++++++--- .../tests/resource_bigquery_table_test.go | 10 +++++----- .../tests/resource_bigtable_instance_test.go | 6 +++--- ...source_cloudfunctions_function_test.go.erb | 10 +++++----- .../resource_composer_environment_test.go.erb | 1 + ...urce_compute_instance_template_test.go.erb | 6 ++++++ .../resource_compute_instance_test.go.erb | 4 ++-- .../tests/resource_google_project_test.go | 2 +- .../terraform/tpgresource/lables.go | 19 +++++++++++++++++++ 16 files changed, 165 insertions(+), 36 deletions(-) create mode 100644 mmv1/third_party/terraform/tpgresource/lables.go diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index 0a33024dafe0..33508cc6326a 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -767,12 +767,20 @@ func ResourceBigQueryTable() *schema.Resource { // start with a letter and each label in the list must have a different // key. "labels": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: `A mapping of labels to assign to the 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.`, + }, + "effective_labels": { Type: schema.TypeMap, - Optional: true, + 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}, - Description: `A mapping of labels to assign to the resource.`, }, - // Schema: [Optional] Describes the schema of this table. // Schema is mutually exclusive with View and Materialized View. "schema": { @@ -1243,9 +1251,12 @@ func resourceBigQueryTableRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("max_staleness", res.MaxStaleness); err != nil { return fmt.Errorf("Error setting max_staleness: %s", err) } - if err := d.Set("labels", res.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(res.Labels, d)); err != nil { return fmt.Errorf("Error setting labels: %s", err) } + if err := d.Set("effective_labels", res.Labels); err != nil { + return fmt.Errorf("Error setting effective_labels: %s", err) + } if err := d.Set("creation_time", res.CreationTime); err != nil { return fmt.Errorf("Error setting creation_time: %s", err) } diff --git a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go index ecb97c65aa52..840e1be46e12 100644 --- a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go +++ b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go @@ -153,10 +153,20 @@ func ResourceBigtableInstance() *schema.Resource { }, "labels": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: `A mapping of labels to assign to the 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.`, + }, + + "effective_labels": { Type: schema.TypeMap, - Optional: true, + 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}, - Description: `A mapping of labels to assign to the resource.`, }, "project": { @@ -301,9 +311,12 @@ func resourceBigtableInstanceRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("display_name", instance.DisplayName); err != nil { return fmt.Errorf("Error setting display_name: %s", err) } - if err := d.Set("labels", instance.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(instance.Labels, d)); err != nil { return fmt.Errorf("Error setting labels: %s", err) } + if err := d.Set("effective_labels", instance.Labels); err != nil { + return fmt.Errorf("Error setting effective_labels: %s", err) + } // Don't set instance_type: we don't want to detect drift on it because it can // change under-the-hood. diff --git a/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go b/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go index 20d26544972a..3d27630c57d3 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go +++ b/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go @@ -257,7 +257,17 @@ func ResourceCloudFunctionsFunction() *schema.Resource { Type: schema.TypeMap, ValidateFunc: labelKeyValidator, Optional: true, - Description: `A set of key/value label pairs to assign to the function. Label keys must follow the requirements at https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements.`, + Description: `A set of key/value label pairs to assign to the function. Label keys must follow the requirements at https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements. + + **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.`, + }, + + "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}, }, "runtime": { @@ -670,9 +680,12 @@ func resourceCloudFunctionsRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("ingress_settings", function.IngressSettings); err != nil { return fmt.Errorf("Error setting ingress_settings: %s", err) } - if err := d.Set("labels", function.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(function.Labels, d)); err != nil { return fmt.Errorf("Error setting labels: %s", err) } + if err := d.Set("effective_labels", function.Labels); err != nil { + return fmt.Errorf("Error setting effective_labels: %s", err) + } if err := d.Set("runtime", function.Runtime); err != nil { return fmt.Errorf("Error setting runtime: %s", err) } diff --git a/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb b/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb index 82e7ea37ac2c..dc642a764e09 100644 --- a/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb +++ b/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb @@ -874,7 +874,17 @@ func ResourceComposerEnvironment() *schema.Resource { Type: schema.TypeMap, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, - Description: `User-defined labels for this environment. The labels map can contain no more than 64 entries. Entries of the labels map are UTF8 strings that comply with the following restrictions: Label keys must be between 1 and 63 characters long and must conform to the following regular expression: [a-z]([-a-z0-9]*[a-z0-9])?. Label values must be between 0 and 63 characters long and must conform to the regular expression ([a-z]([-a-z0-9]*[a-z0-9])?)?. No more than 64 labels can be associated with a given environment. Both keys and values must be <= 128 bytes in size.`, + Description: `User-defined labels for this environment. The labels map can contain no more than 64 entries. Entries of the labels map are UTF8 strings that comply with the following restrictions: Label keys must be between 1 and 63 characters long and must conform to the following regular expression: [a-z]([-a-z0-9]*[a-z0-9])?. Label values must be between 0 and 63 characters long and must conform to the regular expression ([a-z]([-a-z0-9]*[a-z0-9])?)?. No more than 64 labels can be associated with a given environment. Both keys and values must be <= 128 bytes in size. + + **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.`, + }, + + "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}, }, }, UseJSONNumber: true, @@ -978,7 +988,10 @@ func resourceComposerEnvironmentRead(d *schema.ResourceData, meta interface{}) e if err := d.Set("config", flattenComposerEnvironmentConfig(res.Config)); err != nil { return fmt.Errorf("Error setting Environment: %s", err) } - if err := d.Set("labels", res.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(res.Labels, d)); err != nil { + return fmt.Errorf("Error setting Environment: %s", err) + } + if err := d.Set("effective_labels", res.Labels); err != nil { return fmt.Errorf("Error setting Environment: %s", err) } return nil diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb index 59dcba8c061c..bf3f25aeb1a1 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb @@ -598,7 +598,17 @@ func ResourceComputeInstance() *schema.Resource { Type: schema.TypeMap, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, - Description: `A set of key/value label pairs assigned to the instance.`, + Description: `A set of key/value label pairs assigned to the instance. + + **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.`, + }, + + "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}, }, "metadata": { @@ -1375,7 +1385,11 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error } } - if err := d.Set("labels", instance.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(instance.Labels, d)); err != nil { + return err + } + + if err := d.Set("effective_labels", instance.Labels); err != nil { return err } diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb index ee619a6e4f36..3d991d545028 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb @@ -899,7 +899,17 @@ be from 0 to 999,999,999 inclusive.`, ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, - Description: `A set of key/value label pairs to assign to instances created from this template,`, + Description: `A set of key/value label pairs to assign to instances created from this template. + + **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.`, + }, + + "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}, }, "resource_policies": { @@ -1601,10 +1611,13 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{ } } if instanceTemplate.Properties.Labels != nil { - if err := d.Set("labels", instanceTemplate.Properties.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(instanceTemplate.Properties.Labels, d)); err != nil { return fmt.Errorf("Error setting labels: %s", err) } } + if err := d.Set("effective_labels", instanceTemplate.Properties.Labels); err != nil { + return fmt.Errorf("Error setting effective_labels: %s", err) + } if err = d.Set("self_link", instanceTemplate.SelfLink); err != nil { return fmt.Errorf("Error setting self_link: %s", err) } diff --git a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb index 94cd75a6ed99..d1fcd5ceb4dd 100644 --- a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb +++ b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb @@ -144,12 +144,22 @@ func ResourceDataprocJob() *schema.Resource { "labels": { Type: schema.TypeMap, - Description: "Optional. The labels to associate with this job.", + Description: `Optional. The labels to associate with this job. + + **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.`, Optional: true, ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "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}, + }, + "scheduling": { Type: schema.TypeList, Description: "Optional. Job scheduling configuration.", @@ -311,9 +321,12 @@ func resourceDataprocJobRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("force_delete", d.Get("force_delete")); err != nil { return fmt.Errorf("Error setting force_delete: %s", err) } - if err := d.Set("labels", job.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(job.Labels, d)); err != nil { return fmt.Errorf("Error setting labels: %s", err) } + if err := d.Set("effective_labels", job.Labels); err != nil { + return fmt.Errorf("Error setting effective_labels: %s", err) + } if err := d.Set("driver_output_resource_uri", job.DriverOutputResourceUri); err != nil { return fmt.Errorf("Error setting driver_output_resource_uri: %s", err) } diff --git a/mmv1/third_party/terraform/services/resourcemanager/resource_google_project.go b/mmv1/third_party/terraform/services/resourcemanager/resource_google_project.go index cb88fc4c14f8..629ab2b04c29 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/resource_google_project.go +++ b/mmv1/third_party/terraform/services/resourcemanager/resource_google_project.go @@ -103,10 +103,20 @@ func ResourceGoogleProject() *schema.Resource { Description: `The alphanumeric ID of the billing account this project belongs to. The user or service account performing this operation with Terraform must have Billing Account Administrator privileges (roles/billing.admin) in the organization. See Google Cloud Billing API Access Control for more details.`, }, "labels": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: `A set of key/value label pairs to assign to the project. + + **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.`, + }, + + "effective_labels": { Type: schema.TypeMap, - Optional: true, + 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}, - Description: `A set of key/value label pairs to assign to the project.`, }, }, UseJSONNumber: true, @@ -286,9 +296,12 @@ func resourceGoogleProjectRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("name", p.Name); err != nil { return fmt.Errorf("Error setting name: %s", err) } - if err := d.Set("labels", p.Labels); err != nil { + if err := d.Set("labels", tpgresource.FlattenLabels(p.Labels, d)); err != nil { return fmt.Errorf("Error setting labels: %s", err) } + if err := d.Set("effective_labels", p.Labels); err != nil { + return fmt.Errorf("Error setting effective_labels: %s", err) + } if p.Parent != nil { switch p.Parent.Type { diff --git a/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go b/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go index 8cce1b7beb8b..659062418985 100644 --- a/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/tests/resource_bigquery_table_test.go @@ -912,7 +912,7 @@ func TestAccBigQueryDataTable_jsonEquivalency(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, }, { Config: testAccBigQueryTable_jsonEqModeRemoved(datasetID, tableID), @@ -921,7 +921,7 @@ func TestAccBigQueryDataTable_jsonEquivalency(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, }, }, }) @@ -971,7 +971,7 @@ func TestAccBigQueryDataTable_expandArray(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, }, { Config: testAccBigQueryTable_arrayExpanded(datasetID, tableID), @@ -980,7 +980,7 @@ func TestAccBigQueryDataTable_expandArray(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, }, }, }) @@ -1004,7 +1004,7 @@ func TestAccBigQueryTable_allowDestroy(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection"}, + ImportStateVerifyIgnore: []string{"deletion_protection", "labels"}, }, { Config: testAccBigQueryTable_noAllowDestroy(datasetID, tableID), diff --git a/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go b/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go index 39bcb1391d60..baeb17c7d5f3 100644 --- a/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go +++ b/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go @@ -89,7 +89,7 @@ func TestAccBigtableInstance_cluster(t *testing.T) { ResourceName: "google_bigtable_instance.instance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type", "cluster"}, // we don't read instance type back + ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type", "cluster", "labels"}, // we don't read instance type back }, { Config: testAccBigtableInstance_clusterReordered(instanceName, 5), @@ -108,7 +108,7 @@ func TestAccBigtableInstance_cluster(t *testing.T) { ResourceName: "google_bigtable_instance.instance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type", "cluster"}, // we don't read instance type back + ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type", "cluster", "labels"}, // we don't read instance type back }, }, }) @@ -428,7 +428,7 @@ func TestAccBigtableInstance_MultipleClustersSameID(t *testing.T) { ResourceName: "google_bigtable_instance.instance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back + ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type", "labels"}, // we don't read instance type back }, { Config: testAccBigtableInstance_multipleClustersSameID(instanceName), diff --git a/mmv1/third_party/terraform/tests/resource_cloudfunctions_function_test.go.erb b/mmv1/third_party/terraform/tests/resource_cloudfunctions_function_test.go.erb index 1aa75635342f..47735f8ddc2c 100644 --- a/mmv1/third_party/terraform/tests/resource_cloudfunctions_function_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_cloudfunctions_function_test.go.erb @@ -84,7 +84,7 @@ func TestAccCloudFunctionsFunction_basic(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, }, }, }) @@ -121,7 +121,7 @@ func TestAccCloudFunctionsFunction_update(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, }, { Config: testAccCloudFunctionsFunction_updated(functionName, bucketName, zipFileUpdatePath, random_suffix), @@ -154,7 +154,7 @@ func TestAccCloudFunctionsFunction_update(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, }, }, }) @@ -429,7 +429,7 @@ func TestAccCloudFunctionsFunction_vpcConnector(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, }, { Config: testAccCloudFunctionsFunction_vpcConnector(projectNumber, networkName, functionName, bucketName, zipFilePath, "10.20.0.0/28", vpcConnectorName+"-update"), @@ -438,7 +438,7 @@ func TestAccCloudFunctionsFunction_vpcConnector(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb b/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb index d5e7b74f618c..7a84fdb47bcc 100644 --- a/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb @@ -100,6 +100,7 @@ func TestAccComposerEnvironment_update(t *testing.T) { ResourceName: "google_composer_environment.test", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, // This is a terrible clean-up step in order to get destroy to succeed, // due to dangling firewall rules left by the Composer Environment blocking network deletion. diff --git a/mmv1/third_party/terraform/tests/resource_compute_instance_template_test.go.erb b/mmv1/third_party/terraform/tests/resource_compute_instance_template_test.go.erb index d239fcb6cc31..0d83ba1f93af 100644 --- a/mmv1/third_party/terraform/tests/resource_compute_instance_template_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_compute_instance_template_test.go.erb @@ -51,6 +51,7 @@ func TestAccComputeInstanceTemplate_basic(t *testing.T) { ResourceName: "google_compute_instance_template.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -77,6 +78,7 @@ func TestAccComputeInstanceTemplate_imageShorthand(t *testing.T) { ResourceName: "google_compute_instance_template.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -133,6 +135,7 @@ func TestAccComputeInstanceTemplate_maintenance_interval(t *testing.T) { ResourceName: "google_compute_instance_template.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, { Config: testAccComputeInstanceTemplate_basic(acctest.RandString(t, 10)), @@ -589,6 +592,7 @@ func TestAccComputeInstanceTemplate_EncryptKMS(t *testing.T) { ResourceName: "google_compute_instance_template.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -920,6 +924,7 @@ func TestAccComputeInstanceTemplate_diskResourcePolicies(t *testing.T) { ResourceName: "google_compute_instance_template.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) @@ -997,6 +1002,7 @@ func TestAccComputeInstanceTemplate_managedEnvoy(t *testing.T) { ResourceName: "google_compute_instance_template.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/tests/resource_compute_instance_test.go.erb b/mmv1/third_party/terraform/tests/resource_compute_instance_test.go.erb index 938d0a17c864..3c5adc679b57 100644 --- a/mmv1/third_party/terraform/tests/resource_compute_instance_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_compute_instance_test.go.erb @@ -139,7 +139,7 @@ func TestAccComputeInstance_basic1(t *testing.T) { testAccCheckComputeInstanceHasConfiguredDeletionProtection(&instance, false), ), }, - computeInstanceImportStep("us-central1-a", instanceName, []string{"metadata.baz", "metadata.foo", "desired_status", "current_status"}), + computeInstanceImportStep("us-central1-a", instanceName, []string{"metadata.baz", "metadata.foo", "desired_status", "current_status", "labels"}), }, }) } @@ -1401,7 +1401,7 @@ func TestAccComputeInstance_forceChangeMachineTypeManually(t *testing.T) { ), ExpectNonEmptyPlan: true, }, - computeInstanceImportStep("us-central1-a", instanceName, []string{"metadata.baz", "metadata.foo", "desired_status", "current_status"}), + computeInstanceImportStep("us-central1-a", instanceName, []string{"metadata.baz", "metadata.foo", "desired_status", "current_status", "labels"}), }, }) } diff --git a/mmv1/third_party/terraform/tests/resource_google_project_test.go b/mmv1/third_party/terraform/tests/resource_google_project_test.go index 331002899d66..2a0f226537fe 100644 --- a/mmv1/third_party/terraform/tests/resource_google_project_test.go +++ b/mmv1/third_party/terraform/tests/resource_google_project_test.go @@ -135,7 +135,7 @@ func TestAccProject_labels(t *testing.T) { ResourceName: "google_project.acceptance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"skip_delete"}, + ImportStateVerifyIgnore: []string{"skip_delete", "labels"}, }, // update project with labels { diff --git a/mmv1/third_party/terraform/tpgresource/lables.go b/mmv1/third_party/terraform/tpgresource/lables.go new file mode 100644 index 000000000000..1e76a2aeb35c --- /dev/null +++ b/mmv1/third_party/terraform/tpgresource/lables.go @@ -0,0 +1,19 @@ +package tpgresource + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func FlattenLabels(labels map[string]string, d *schema.ResourceData) map[string]interface{} { + transformed := make(map[string]interface{}) + + if v, ok := d.GetOk("labels"); ok { + if labels != nil { + for k, _ := range v.(map[string]interface{}) { + transformed[k] = labels[k] + } + } + } + + return transformed +} From 5b240fd3536510936fba02e5c81a7a550e8d01cd Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Fri, 18 Aug 2023 10:45:46 -0700 Subject: [PATCH 013/476] Remove Terraform support for game services (#8669) * Remove Terraform support for game services * Remove game_service from provider.go * Remove gameServices from ci file --- .ci/infra/terraform/main.tf | 1 - .../gameservices/GameServerCluster.yaml | 137 -------------- .../gameservices/GameServerConfig.yaml | 176 ------------------ .../gameservices/GameServerDeployment.yaml | 87 --------- .../GameServerDeploymentRollout.yaml | 106 ----------- mmv1/products/gameservices/Realm.yaml | 90 --------- mmv1/products/gameservices/product.yaml | 25 --- .../gameservice_rollout_create.go | 16 -- .../game_service_cluster_basic.tf.erb | 62 ------ .../examples/game_service_config_basic.tf.erb | 30 --- .../game_service_deployment_basic.tf.erb | 5 - ...me_service_deployment_rollout_basic.tf.erb | 23 --- .../examples/game_service_realm_basic.tf.erb | 8 - .../terraform/provider/provider.go.erb | 1 - ...services_game_server_deployment_rollout.go | 33 ---- ...me_server_deployment_rollout.html.markdown | 68 ------- 16 files changed, 868 deletions(-) delete mode 100644 mmv1/products/gameservices/GameServerCluster.yaml delete mode 100644 mmv1/products/gameservices/GameServerConfig.yaml delete mode 100644 mmv1/products/gameservices/GameServerDeployment.yaml delete mode 100644 mmv1/products/gameservices/GameServerDeploymentRollout.yaml delete mode 100644 mmv1/products/gameservices/Realm.yaml delete mode 100644 mmv1/products/gameservices/product.yaml delete mode 100644 mmv1/templates/terraform/custom_create/gameservice_rollout_create.go delete mode 100644 mmv1/templates/terraform/examples/game_service_cluster_basic.tf.erb delete mode 100644 mmv1/templates/terraform/examples/game_service_config_basic.tf.erb delete mode 100644 mmv1/templates/terraform/examples/game_service_deployment_basic.tf.erb delete mode 100644 mmv1/templates/terraform/examples/game_service_deployment_rollout_basic.tf.erb delete mode 100644 mmv1/templates/terraform/examples/game_service_realm_basic.tf.erb delete mode 100644 mmv1/third_party/terraform/services/gameservices/data_source_google_game_services_game_server_deployment_rollout.go delete mode 100644 mmv1/third_party/terraform/website/docs/d/game_services_game_server_deployment_rollout.html.markdown diff --git a/.ci/infra/terraform/main.tf b/.ci/infra/terraform/main.tf index fa6d3a584595..24380f7fbde8 100644 --- a/.ci/infra/terraform/main.tf +++ b/.ci/infra/terraform/main.tf @@ -241,7 +241,6 @@ module "project-services" { "firebasestorage.googleapis.com", "firestore.googleapis.com", "firestorekeyvisualizer.googleapis.com", - "gameservices.googleapis.com", "gkebackup.googleapis.com", "gkeconnect.googleapis.com", "gkehub.googleapis.com", diff --git a/mmv1/products/gameservices/GameServerCluster.yaml b/mmv1/products/gameservices/GameServerCluster.yaml deleted file mode 100644 index 8f768c02bfa6..000000000000 --- a/mmv1/products/gameservices/GameServerCluster.yaml +++ /dev/null @@ -1,137 +0,0 @@ -# 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: GameServerCluster -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/game-servers/docs' - api: 'https://cloud.google.com/game-servers/docs/reference/rest/v1beta/projects.locations.realms.gameServerClusters' -update_verb: :PATCH -update_mask: true -base_url: projects/{{project}}/locations/{{location}}/realms/{{realm_id}}/gameServerClusters -create_url: projects/{{project}}/locations/{{location}}/realms/{{realm_id}}/gameServerClusters?gameServerClusterId={{cluster_id}} -self_link: projects/{{project}}/locations/{{location}}/realms/{{realm_id}}/gameServerClusters/{{cluster_id}} -description: A game server cluster resource. -async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: true - allowed: - - true - - false - error: !ruby/object:Api::OpAsync::Error - path: 'error/errors' - message: 'message' -import_format: - [ - 'projects/{{project}}/locations/{{location}}/realms/{{realm_id}}/gameServerClusters/{{cluster_id}}', - ] -# Skipping the sweeper due to the non-standard base_url -skip_sweeper: true -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'game_service_cluster_basic' - primary_resource_id: - 'default' - skip_test: true - vars: - realm_id: 'realm' - test_vars_overrides: - agones_cluster: '"bootstrapped-agones-cluster"' -custom_code: !ruby/object:Provider::Terraform::CustomCode - constants: 'templates/terraform/constants/gameserver_cluster_custom_diff.go' -properties: - - !ruby/object:Api::Type::String - immutable: true - name: clusterId - required: true - url_param_only: true - description: |- - Required. The resource name of the game server cluster - - !ruby/object:Api::Type::String - name: name - output: true - description: |- - The resource id of the game server cluster, eg: - - `projects/{project_id}/locations/{location}/realms/{realm_id}/gameServerClusters/{cluster_id}`. - For example, - - `projects/my-project/locations/{location}/realms/zanzibar/gameServerClusters/my-onprem-cluster`. - - !ruby/object:Api::Type::ResourceRef - name: realmId - url_param_only: true - resource: Realm - imports: name - required: true - description: |- - The realm id of the game server realm. - - !ruby/object:Api::Type::String - name: location - url_param_only: true - default_value: global - description: Location of the Cluster. - - !ruby/object:Api::Type::KeyValuePairs - name: labels - description: |- - The labels associated with this game server cluster. Each label is a - key-value pair. - - !ruby/object:Api::Type::NestedObject - name: connectionInfo - required: true - immutable: true - description: |- - Game server cluster connection information. This information is used to - manage game server clusters. - properties: - - !ruby/object:Api::Type::NestedObject - name: gkeClusterReference - required: true - immutable: true - description: - Reference of the GKE cluster where the game servers are installed. - properties: - - !ruby/object:Api::Type::String - name: cluster - required: true - immutable: true - description: |- - The full or partial name of a GKE cluster, using one of the following - forms: - - * `projects/{project_id}/locations/{location}/clusters/{cluster_id}` - * `locations/{location}/clusters/{cluster_id}` - * `{cluster_id}` - - If project and location are not specified, the project and location of the - GameServerCluster resource are used to generate the full name of the - GKE cluster. - diff_suppress_func: suppressSuffixDiff - - !ruby/object:Api::Type::String - name: namespace - required: true - description: |- - Namespace designated on the game server cluster where the game server - instances will be created. The namespace existence will be validated - during creation. - - !ruby/object:Api::Type::String - name: description - description: Human readable description of the cluster. diff --git a/mmv1/products/gameservices/GameServerConfig.yaml b/mmv1/products/gameservices/GameServerConfig.yaml deleted file mode 100644 index 75de43ab2eb0..000000000000 --- a/mmv1/products/gameservices/GameServerConfig.yaml +++ /dev/null @@ -1,176 +0,0 @@ -# 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: GameServerConfig -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/game-servers/docs' - api: 'https://cloud.google.com/game-servers/docs/reference/rest/v1beta/projects.locations.gameServerDeployments.configs' -create_url: projects/{{project}}/locations/{{location}}/gameServerDeployments/{{deployment_id}}/configs?configId={{config_id}} -base_url: projects/{{project}}/locations/{{location}}/gameServerDeployments/{{deployment_id}}/configs -self_link: projects/{{project}}/locations/{{location}}/gameServerDeployments/{{deployment_id}}/configs/{{config_id}} -immutable: true -async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: true - allowed: - - true - - false - error: !ruby/object:Api::OpAsync::Error - path: 'error/errors' - message: 'message' -description: A game server config resource. Configs are global and immutable. -autogen_async: true -import_format: - [ - 'projects/{{project}}/locations/{{location}}/gameServerDeployments/{{deployment_id}}/configs/{{config_id}}', - ] -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'game_service_config_basic' - primary_resource_id: 'default' - skip_test: true - vars: - deployment_id: 'tf-test-deployment' - config_id: 'tf-test-config' -properties: - - !ruby/object:Api::Type::String - name: name - output: true - description: |- - The resource name of the game server config, in the form: - - `projects/{project_id}/locations/{location}/gameServerDeployments/{deployment_id}/configs/{config_id}`. - - !ruby/object:Api::Type::String - name: configId - immutable: true - required: true - url_param_only: true - description: | - A unique id for the deployment config. - - !ruby/object:Api::Type::String - name: location - # The only acceptable location currently is 'global' - # TODO - either hard code or set as computed - url_param_only: true - default_value: global - description: Location of the Deployment. - - !ruby/object:Api::Type::ResourceRef - name: deploymentId - resource: 'GameServerDeployment' - imports: 'deploymentId' - immutable: true - required: true - url_param_only: true - description: | - A unique id for the deployment. - - !ruby/object:Api::Type::String - name: description - description: The description of the game server config. - - !ruby/object:Api::Type::KeyValuePairs - name: labels - description: |- - The labels associated with this game server config. Each label is a - key-value pair. - - !ruby/object:Api::Type::Array - name: fleetConfigs - required: true - description: |- - The fleet config contains list of fleet specs. In the Single Cloud, there - will be only one. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - required: true - name: fleetSpec - description: | - The fleet spec, which is sent to Agones to configure fleet. - The spec can be passed as inline json but it is recommended to use a file reference - instead. File references can contain the json or yaml format of the fleet spec. Eg: - - * fleet_spec = jsonencode(yamldecode(file("fleet_configs.yaml"))) - * fleet_spec = file("fleet_configs.json") - - The format of the spec can be found : - `https://agones.dev/site/docs/reference/fleet/`. - - !ruby/object:Api::Type::String - name: name - required: true - description: The name of the FleetConfig. - default_from_api: true - - !ruby/object:Api::Type::Array - name: scalingConfigs - description: Optional. This contains the autoscaling settings. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: name - required: true - description: The name of the ScalingConfig - - !ruby/object:Api::Type::String - required: true - name: fleetAutoscalerSpec - description: |- - Fleet autoscaler spec, which is sent to Agones. - Example spec can be found : - https://agones.dev/site/docs/reference/fleetautoscaler/ - - !ruby/object:Api::Type::Array - name: selectors - description: |- - Labels used to identify the clusters to which this scaling config - applies. A cluster is subject to this scaling config if its labels match - any of the selector entries. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::KeyValuePairs - name: labels - description: Set of labels to group by. - - !ruby/object:Api::Type::Array - name: schedules - description: The schedules to which this scaling config applies. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: startTime - description: |- - The start time of the event. - - A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z". - - !ruby/object:Api::Type::String - name: endTime - description: |- - The end time of the event. - - A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z". - - !ruby/object:Api::Type::String - name: cronJobDuration - description: |- - The duration for the cron job event. The duration of the event is effective - after the cron job's start time. - - A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s". - - !ruby/object:Api::Type::String - name: cronSpec - description: |- - The cron definition of the scheduled event. See - https://en.wikipedia.org/wiki/Cron. Cron spec specifies the local time as - defined by the realm. diff --git a/mmv1/products/gameservices/GameServerDeployment.yaml b/mmv1/products/gameservices/GameServerDeployment.yaml deleted file mode 100644 index 041d44def02e..000000000000 --- a/mmv1/products/gameservices/GameServerDeployment.yaml +++ /dev/null @@ -1,87 +0,0 @@ -# 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: GameServerDeployment -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/game-servers/docs' - api: 'https://cloud.google.com/game-servers/docs/reference/rest/v1beta/projects.locations.gameServerDeployments' -base_url: projects/{{project}}/locations/{{location}}/gameServerDeployments -create_url: projects/{{project}}/locations/{{location}}/gameServerDeployments?deploymentId={{deployment_id}} -self_link: projects/{{project}}/locations/{{location}}/gameServerDeployments/{{deployment_id}} -update_mask: true -update_verb: :PATCH -description: A game server deployment resource. -async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: true - allowed: - - true - - false - error: !ruby/object:Api::OpAsync::Error - path: 'error/errors' - message: 'message' -autogen_async: true -import_format: - [ - 'projects/{{project}}/locations/{{location}}/gameServerDeployments/{{deployment_id}}', - ] -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'game_service_deployment_basic' - primary_resource_id: 'default' - skip_test: true - vars: - deployment_id: 'tf-test-deployment' -properties: - - !ruby/object:Api::Type::String - name: name - output: true - description: |- - The resource id of the game server deployment, eg: - - `projects/{project_id}/locations/{location}/gameServerDeployments/{deployment_id}`. - For example, - - `projects/my-project/locations/{location}/gameServerDeployments/my-deployment`. - - !ruby/object:Api::Type::String - name: description - description: Human readable description of the game server deployment. - - !ruby/object:Api::Type::String - name: deploymentId - immutable: true - required: true - url_param_only: true - description: | - A unique id for the deployment. - - !ruby/object:Api::Type::String - name: location - # The only acceptable location currently is 'global' - # TODO - either hard code or set as computed - url_param_only: true - default_value: global - description: Location of the Deployment. - - !ruby/object:Api::Type::KeyValuePairs - name: labels - description: |- - The labels associated with this game server deployment. Each label is a - key-value pair. diff --git a/mmv1/products/gameservices/GameServerDeploymentRollout.yaml b/mmv1/products/gameservices/GameServerDeploymentRollout.yaml deleted file mode 100644 index 3b9cad5296de..000000000000 --- a/mmv1/products/gameservices/GameServerDeploymentRollout.yaml +++ /dev/null @@ -1,106 +0,0 @@ -# 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: GameServerDeploymentRollout -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/game-servers/docs' - api: 'https://cloud.google.com/game-servers/docs/reference/rest/v1beta/GameServerDeploymentRollout' -create_url: projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout -base_url: projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout -update_url: projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout -# Deleting a rollout is synonymous with removing the default game server config -delete_url: projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout?updateMask=defaultGameServerConfig -update_verb: :PATCH -delete_verb: :PATCH -update_mask: true -self_link: projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout -async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: true - allowed: - - true - - false - error: !ruby/object:Api::OpAsync::Error - path: 'error/errors' - message: 'message' -description: |- - This represents the rollout state. This is part of the game server - deployment. -import_format: - [ - 'projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout', - ] -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'game_service_deployment_rollout_basic' - primary_resource_id: 'default' - skip_test: true - vars: - deployment_id: 'tf-test-deployment' - config_id: 'tf-test-config' -custom_code: !ruby/object:Provider::Terraform::CustomCode - custom_create: 'templates/terraform/custom_create/gameservice_rollout_create.go' -properties: - - !ruby/object:Api::Type::String - name: name - output: true - description: |- - The resource id of the game server deployment - - eg: `projects/my-project/locations/global/gameServerDeployments/my-deployment/rollout`. - - !ruby/object:Api::Type::ResourceRef - name: deploymentId - resource: GameServerDeployment - url_param_only: true - required: true - imports: name - description: | - The deployment to rollout the new config to. Only 1 rollout must be associated with each deployment. - - !ruby/object:Api::Type::String - name: defaultGameServerConfig - required: true - description: |- - This field points to the game server config that is - applied by default to all realms and clusters. For example, - - `projects/my-project/locations/global/gameServerDeployments/my-game/configs/my-config`. - - !ruby/object:Api::Type::Array - name: gameServerConfigOverrides - description: |- - The game_server_config_overrides contains the per game server config - overrides. The overrides are processed in the order they are listed. As - soon as a match is found for a cluster, the rest of the list is not - processed. - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::NestedObject - name: realmsSelector - description: Selection by realms. - properties: - - !ruby/object:Api::Type::Array - name: realms - description: List of realms to match against. - item_type: Api::Type::String - - !ruby/object:Api::Type::String - name: configVersion - description: Version of the configuration. diff --git a/mmv1/products/gameservices/Realm.yaml b/mmv1/products/gameservices/Realm.yaml deleted file mode 100644 index 07a0f6f2c650..000000000000 --- a/mmv1/products/gameservices/Realm.yaml +++ /dev/null @@ -1,90 +0,0 @@ -# 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: Realm -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/game-servers/docs' - api: 'https://cloud.google.com/game-servers/docs/reference/rest/v1beta/projects.locations.realms' -create_url: projects/{{project}}/locations/{{location}}/realms?realmId={{realm_id}} -base_url: projects/{{project}}/locations/{{location}}/realms -self_link: projects/{{project}}/locations/{{location}}/realms/{{realm_id}} -update_verb: :PATCH -update_mask: true -description: A Realm resource. -async: !ruby/object:Api::OpAsync - operation: !ruby/object:Api::OpAsync::Operation - path: 'name' - base_url: '{{op_id}}' - wait_ms: 1000 - result: !ruby/object:Api::OpAsync::Result - path: 'response' - resource_inside_response: true - status: !ruby/object:Api::OpAsync::Status - path: 'done' - complete: true - allowed: - - true - - false - error: !ruby/object:Api::OpAsync::Error - path: 'error/errors' - message: 'message' -autogen_async: true -import_format: - ['projects/{{project}}/locations/{{location}}/realms/{{realm_id}}'] -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'game_service_realm_basic' - primary_resource_id: 'default' - skip_test: true - vars: - realm_id: 'tf-test-realm' -parameters: - - !ruby/object:Api::Type::String - name: location - url_param_only: true - default_value: global - description: Location of the Realm. - - !ruby/object:Api::Type::String - name: realmId - immutable: true - url_param_only: true - required: true - description: GCP region of the Realm. -properties: - - !ruby/object:Api::Type::String - name: name - output: true - description: |- - The resource id of the realm, of the form: - `projects/{project_id}/locations/{location}/realms/{realm_id}`. For - example, `projects/my-project/locations/{location}/realms/my-realm`. - - !ruby/object:Api::Type::KeyValuePairs - name: labels - description: - The labels associated with this realm. Each label is a key-value pair. - - !ruby/object:Api::Type::String - name: timeZone - required: true - description: |- - Required. Time zone where all realm-specific policies are evaluated. The value of - this field must be from the IANA time zone database: - https://www.iana.org/time-zones. - - !ruby/object:Api::Type::String - name: etag - output: true - description: ETag of the resource. - - !ruby/object:Api::Type::String - name: description - description: Human readable description of the realm. diff --git a/mmv1/products/gameservices/product.yaml b/mmv1/products/gameservices/product.yaml deleted file mode 100644 index 45ddaf0b3d6d..000000000000 --- a/mmv1/products/gameservices/product.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2019 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::Product -name: GameServices -display_name: Game Servers -scopes: - - https://www.googleapis.com/auth/compute -versions: - - !ruby/object:Api::Product::Version - name: ga - base_url: https://gameservices.googleapis.com/v1/ - - !ruby/object:Api::Product::Version - name: beta - base_url: https://gameservices.googleapis.com/v1beta/ diff --git a/mmv1/templates/terraform/custom_create/gameservice_rollout_create.go b/mmv1/templates/terraform/custom_create/gameservice_rollout_create.go deleted file mode 100644 index 85da871cd049..000000000000 --- a/mmv1/templates/terraform/custom_create/gameservice_rollout_create.go +++ /dev/null @@ -1,16 +0,0 @@ -// Store the ID now -id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout") -if err != nil { - return fmt.Errorf("Error constructing id: %s", err) -} -d.SetId(id) - -log.Printf("[DEBUG] Creating GameServerDeploymentRollout %q: ", d.Id()) - -err = resourceGameServicesGameServerDeploymentRolloutUpdate(d, meta) -if err != nil { - d.SetId("") - return fmt.Errorf("Error trying to create GameServerDeploymentRollout: %s", err) -} - -return nil diff --git a/mmv1/templates/terraform/examples/game_service_cluster_basic.tf.erb b/mmv1/templates/terraform/examples/game_service_cluster_basic.tf.erb deleted file mode 100644 index 19eb85571952..000000000000 --- a/mmv1/templates/terraform/examples/game_service_cluster_basic.tf.erb +++ /dev/null @@ -1,62 +0,0 @@ -resource "google_game_services_game_server_cluster" "<%= ctx[:primary_resource_id] %>" { - <%# depends_on = [google_project_iam_member.kubernetes_developer] -%> - <%# depends_on = [module.agones_cluster, module.helm_agones] -%> - - cluster_id = "<%= ctx[:vars]['agones_cluster'] %>" - realm_id = google_game_services_realm.default.realm_id - - connection_info { - gke_cluster_reference { - cluster = "locations/us-west1/clusters/%{agones_cluster}" - } - namespace = "default" - } -} - -resource "google_game_services_realm" "default" { - realm_id = "<%= ctx[:vars]["realm_id"] %>" - time_zone = "PST8PDT" - - description = "Test Game Realm" -} - - -<%# -This resource requires that a GKE cluster is already created with Agones provisioned -and configured correctly for this test to succeed. Since this setup requires a fair amount -of bootstrapping that is non-essential to testing that the resource works we've decided to -set up the cluster in advance and run the tests against it. The following Terraform config -was used to provision the cluster. Since it is a manual set up this config not guaranteed to -work out of the box. - -module "agones_cluster" { - source = "git::https://github.com/googleforgames/agones.git//install/terraform/modules/gke/?ref=release-1.4.0" - - cluster = { - "name" = var.name - "zone" = "us-west1" - "machineType" = "e2-standard-4" - "initialNodeCount" = 1 - "project" = "" - "network" = "default" - } -} - -// Install Agones via Helm -module "helm_agones" { - source = "git::https://github.com/googleforgames/agones.git//install/terraform/modules/helm/?ref=release-1.4.0" - - agones_version = "1.4.0" - values_file = "" - chart = "agones" - host = module.agones_cluster.host - token = module.agones_cluster.token - cluster_ca_certificate = module.agones_cluster.cluster_ca_certificate -} - -resource "google_project_iam_member" "agent_create" { - project = var.project - role = "roles/container.developer" - member = "serviceAccount:service-@gcp-sa-gameservices.iam.gserviceaccount.com" -} --%> \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/game_service_config_basic.tf.erb b/mmv1/templates/terraform/examples/game_service_config_basic.tf.erb deleted file mode 100644 index 6c89cbcf8f7c..000000000000 --- a/mmv1/templates/terraform/examples/game_service_config_basic.tf.erb +++ /dev/null @@ -1,30 +0,0 @@ -resource "google_game_services_game_server_deployment" "default" { - deployment_id = "<%= ctx[:vars]["deployment_id"] %>" - description = "a deployment description" -} - -resource "google_game_services_game_server_config" "<%= ctx[:primary_resource_id] %>" { - config_id = "<%= ctx[:vars]["config_id"] %>" - deployment_id = google_game_services_game_server_deployment.default.deployment_id - description = "a config description" - - fleet_configs { - name = "something-unique" - fleet_spec = jsonencode({ "replicas" : 1, "scheduling" : "Packed", "template" : { "metadata" : { "name" : "tf-test-game-server-template" }, "spec" : { "ports": [{"name": "default", "portPolicy": "Dynamic", "containerPort": 7654, "protocol": "UDP"}], "template" : { "spec" : { "containers" : [{ "name" : "simple-udp-server", "image" : "gcr.io/agones-images/udp-server:0.14" }] } } } } }) - } - - scaling_configs { - name = "scaling-config-name" - fleet_autoscaler_spec = jsonencode({"policy": {"type": "Webhook","webhook": {"service": {"name": "autoscaler-webhook-service","namespace": "default","path": "scale"}}}}) - selectors { - labels = { - "one" : "two" - } - } - - schedules { - cron_job_duration = "3.500s" - cron_spec = "0 0 * * 0" - } - } -} diff --git a/mmv1/templates/terraform/examples/game_service_deployment_basic.tf.erb b/mmv1/templates/terraform/examples/game_service_deployment_basic.tf.erb deleted file mode 100644 index 10e00ebc6ace..000000000000 --- a/mmv1/templates/terraform/examples/game_service_deployment_basic.tf.erb +++ /dev/null @@ -1,5 +0,0 @@ -resource "google_game_services_game_server_deployment" "<%= ctx[:primary_resource_id] %>" { - deployment_id = "<%= ctx[:vars]["deployment_id"] %>" - description = "a deployment description" -} - diff --git a/mmv1/templates/terraform/examples/game_service_deployment_rollout_basic.tf.erb b/mmv1/templates/terraform/examples/game_service_deployment_rollout_basic.tf.erb deleted file mode 100644 index 8d41a0ddd382..000000000000 --- a/mmv1/templates/terraform/examples/game_service_deployment_rollout_basic.tf.erb +++ /dev/null @@ -1,23 +0,0 @@ -resource "google_game_services_game_server_deployment" "default" { - deployment_id = "<%= ctx[:vars]["deployment_id"] %>" - description = "a deployment description" -} - -resource "google_game_services_game_server_config" "default" { - config_id = "<%= ctx[:vars]["config_id"] %>" - deployment_id = google_game_services_game_server_deployment.default.deployment_id - description = "a config description" - - fleet_configs { - name = "some-non-guid" - fleet_spec = jsonencode({ "replicas" : 1, "scheduling" : "Packed", "template" : { "metadata" : { "name" : "tf-test-game-server-template" }, "spec" : { "ports": [{"name": "default", "portPolicy": "Dynamic", "containerPort": 7654, "protocol": "UDP"}], "template" : { "spec" : { "containers" : [{ "name" : "simple-udp-server", "image" : "gcr.io/agones-images/udp-server:0.14" }] } } } } }) - - // Alternate usage: - // fleet_spec = file(fleet_configs.json) - } -} - -resource "google_game_services_game_server_deployment_rollout" "<%= ctx[:primary_resource_id] %>" { - deployment_id = google_game_services_game_server_deployment.default.deployment_id - default_game_server_config = google_game_services_game_server_config.default.name -} diff --git a/mmv1/templates/terraform/examples/game_service_realm_basic.tf.erb b/mmv1/templates/terraform/examples/game_service_realm_basic.tf.erb deleted file mode 100644 index 0385c37a6f2c..000000000000 --- a/mmv1/templates/terraform/examples/game_service_realm_basic.tf.erb +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_game_services_realm" "<%= ctx[:primary_resource_id] %>" { - realm_id = "<%= ctx[:vars]["realm_id"] %>" - time_zone = "EST" - location = "global" - - description = "one of the nine" -} - diff --git a/mmv1/third_party/terraform/provider/provider.go.erb b/mmv1/third_party/terraform/provider/provider.go.erb index 7aa937faf4f3..851680b5ca35 100644 --- a/mmv1/third_party/terraform/provider/provider.go.erb +++ b/mmv1/third_party/terraform/provider/provider.go.erb @@ -274,7 +274,6 @@ func DatasourceMapWithErrors() (map[string]*schema.Resource, error) { "google_container_registry_repository": containeranalysis.DataSourceGoogleContainerRepo(), "google_dataproc_metastore_service": dataprocmetastore.DataSourceDataprocMetastoreService(), "google_datastream_static_ips": datastream.DataSourceGoogleDatastreamStaticIps(), - "google_game_services_game_server_deployment_rollout": gameservices.DataSourceGameServicesGameServerDeploymentRollout(), "google_iam_policy": resourcemanager.DataSourceGoogleIamPolicy(), "google_iam_role": resourcemanager.DataSourceGoogleIamRole(), "google_iam_testable_permissions": resourcemanager.DataSourceGoogleIamTestablePermissions(), diff --git a/mmv1/third_party/terraform/services/gameservices/data_source_google_game_services_game_server_deployment_rollout.go b/mmv1/third_party/terraform/services/gameservices/data_source_google_game_services_game_server_deployment_rollout.go deleted file mode 100644 index ab8d406cafdb..000000000000 --- a/mmv1/third_party/terraform/services/gameservices/data_source_google_game_services_game_server_deployment_rollout.go +++ /dev/null @@ -1,33 +0,0 @@ -package gameservices - -import ( - "fmt" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-provider-google/google/tpgresource" - transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" -) - -func DataSourceGameServicesGameServerDeploymentRollout() *schema.Resource { - - dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceGameServicesGameServerDeploymentRollout().Schema) - tpgresource.AddRequiredFieldsToSchema(dsSchema, "deployment_id") - - return &schema.Resource{ - Read: dataSourceGameServicesGameServerDeploymentRolloutRead, - Schema: dsSchema, - } -} - -func dataSourceGameServicesGameServerDeploymentRolloutRead(d *schema.ResourceData, meta interface{}) error { - config := meta.(*transport_tpg.Config) - - id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout") - if err != nil { - return fmt.Errorf("Error constructing id: %s", err) - } - - d.SetId(id) - - return resourceGameServicesGameServerDeploymentRolloutRead(d, meta) -} diff --git a/mmv1/third_party/terraform/website/docs/d/game_services_game_server_deployment_rollout.html.markdown b/mmv1/third_party/terraform/website/docs/d/game_services_game_server_deployment_rollout.html.markdown deleted file mode 100644 index 263c218a36da..000000000000 --- a/mmv1/third_party/terraform/website/docs/d/game_services_game_server_deployment_rollout.html.markdown +++ /dev/null @@ -1,68 +0,0 @@ ---- -subcategory: "Game Servers" -description: |- - Get the rollout state. ---- - -# google\_game\_services\_game\_server\_deployment\_rollout - -Use this data source to get the rollout state. - -https://cloud.google.com/game-servers/docs/reference/rest/v1beta/GameServerDeploymentRollout - -## Example Usage - - -```hcl -data "google_game_services_game_server_deployment_rollout" "qa" { - deployment_id = "tf-test-deployment-s8sn12jt2c" -} -``` - -## Argument Reference - -The following arguments are supported: - - -* `deployment_id` - (Required) - The deployment to get the rollout state from. Only 1 rollout must be associated with each deployment. - - -## Attributes Reference - -In addition to the arguments listed above, the following attributes are exported: - -* `default_game_server_config` - - This field points to the game server config that is - applied by default to all realms and clusters. For example, - `projects/my-project/locations/global/gameServerDeployments/my-game/configs/my-config`. - - -* `game_server_config_overrides` - - The game_server_config_overrides contains the per game server config - overrides. The overrides are processed in the order they are listed. As - soon as a match is found for a cluster, the rest of the list is not - processed. Structure is [documented below](#nested_game_server_config_overrides). - -* `project` - The ID of the project in which the resource belongs. - If it is not provided, the provider project is used. - - -The `game_server_config_overrides` block contains: - -* `realms_selector` - - Selection by realms. Structure is [documented below](#nested_realms_selector). - -* `config_version` - - Version of the configuration. - -The `realms_selector` block contains: - -* `realms` - - List of realms to match against. - -* `id` - an identifier for the resource with format `projects/{{project}}/locations/global/gameServerDeployments/{{deployment_id}}/rollout` - -* `name` - - The resource id of the game server deployment - eg: `projects/my-project/locations/global/gameServerDeployments/my-deployment/rollout`. From 7d4ce179b67cf52900bf989e0bc6d56a56bc3653 Mon Sep 17 00:00:00 2001 From: Scott Suarez Date: Wed, 23 Aug 2023 12:14:41 -0700 Subject: [PATCH 014/476] Use base branch for pre-build validation merge (#8748) --- .github/workflows/pre-build-validation-on-pr.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pre-build-validation-on-pr.yml b/.github/workflows/pre-build-validation-on-pr.yml index 93f845708c5f..d8741fd52cf2 100644 --- a/.github/workflows/pre-build-validation-on-pr.yml +++ b/.github/workflows/pre-build-validation-on-pr.yml @@ -20,8 +20,9 @@ jobs: cd repo git config user.name "modular-magician" git config user.email "magic-modules@google.com" - git merge --no-ff origin/main - yamlfiles=$(git diff --name-only origin/main -- mmv1/products) + git fetch origin ${{ github.base_ref }} # Fetch the base branch + git merge --no-ff origin/${{ github.base_ref }} # Merge with the base branch + yamlfiles=$(git diff --name-only origin/${{ github.base_ref }} -- mmv1/products) # Compare with the base branch if [ ! -z "$yamlfiles" ]; then echo "yamlfiles=repo/${yamlfiles//$'\n'/ repo/}" >> $GITHUB_OUTPUT fi From 91bbdc516cae8c86a16f476fb137f02ab99a76c5 Mon Sep 17 00:00:00 2001 From: Shuya Ma Date: Wed, 23 Aug 2023 13:15:11 -0700 Subject: [PATCH 015/476] fix yaml lint errors --- mmv1/products/compute/RegionSecurityPolicyRule.yaml | 2 +- mmv1/products/filestore/Instance.yaml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mmv1/products/compute/RegionSecurityPolicyRule.yaml b/mmv1/products/compute/RegionSecurityPolicyRule.yaml index 8580b3281d90..fecb3ca06c05 100644 --- a/mmv1/products/compute/RegionSecurityPolicyRule.yaml +++ b/mmv1/products/compute/RegionSecurityPolicyRule.yaml @@ -65,7 +65,7 @@ examples: - !ruby/object:Provider::Terraform::Examples name: 'region_security_policy_rule_with_network_match' # it needs to run synchronously because a region can have only one google_compute_network_edge_security_service. - # there is a robust handwritten test which covers this scenario. + # there is a robust handwritten test which covers this scenario. skip_test: true primary_resource_id: 'policy_rule_network_match' min_version: 'beta' diff --git a/mmv1/products/filestore/Instance.yaml b/mmv1/products/filestore/Instance.yaml index 12ca3ef1d256..2abe2a296123 100644 --- a/mmv1/products/filestore/Instance.yaml +++ b/mmv1/products/filestore/Instance.yaml @@ -44,7 +44,8 @@ examples: - !ruby/object:Provider::Terraform::Examples name: 'filestore_instance_enterprise' primary_resource_id: 'instance' - skip_test: true # https://github.com/GoogleCloudPlatform/magic-modules/pull/5875#discussion_r844285335 + # https://github.com/GoogleCloudPlatform/magic-modules/pull/5875#discussion_r844285335 + skip_test: true vars: instance_name: 'test-instance' custom_code: !ruby/object:Provider::Terraform::CustomCode From ac907790465771501b21daf315486f8994518126 Mon Sep 17 00:00:00 2001 From: Shuya Ma Date: Thu, 24 Aug 2023 00:42:27 -0700 Subject: [PATCH 016/476] added back Datascan changes --- mmv1/products/dataplex/Datascan.yaml | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/mmv1/products/dataplex/Datascan.yaml b/mmv1/products/dataplex/Datascan.yaml index 7178853c122a..eaababbcac5e 100644 --- a/mmv1/products/dataplex/Datascan.yaml +++ b/mmv1/products/dataplex/Datascan.yaml @@ -445,3 +445,44 @@ properties: name: 'rowFilter' description: | A filter applied to all rows in a single DataScan job. The filter needs to be a valid SQL expression for a WHERE clause in BigQuery standard SQL syntax. Example: col1 >= 0 AND col2 < 10 + - !ruby/object:Api::Type::NestedObject + name: 'postScanActions' + description: | + Actions to take upon job completion. + properties: + - !ruby/object:Api::Type::NestedObject + name: 'bigqueryExport' + description: | + If set, results will be exported to the provided BigQuery table. + properties: + - !ruby/object:Api::Type::String + name: 'resultsTable' + description: | + The BigQuery table to export DataProfileScan results to. + Format://bigquery.googleapis.com/projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID + - !ruby/object:Api::Type::NestedObject + name: 'includeFields' + description: | + The fields to include in data profile. + If not specified, all fields at the time of profile scan job execution are included, except for ones listed in `exclude_fields`. + properties: + - !ruby/object:Api::Type::Array + name: 'fieldNames' + description: | + Expected input is a list of fully qualified names of fields as in the schema. + Only top-level field names for nested fields are supported. + For instance, if 'x' is of nested field type, listing 'x' is supported but 'x.y.z' is not supported. Here 'y' and 'y.z' are nested fields of 'x'. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: 'excludeFields' + description: | + The fields to exclude from data profile. + If specified, the fields will be excluded from data profile, regardless of `include_fields` value. + properties: + - !ruby/object:Api::Type::Array + name: 'fieldNames' + description: | + Expected input is a list of fully qualified names of fields as in the schema. + Only top-level field names for nested fields are supported. + For instance, if 'x' is of nested field type, listing 'x' is supported but 'x.y.z' is not supported. Here 'y' and 'y.z' are nested fields of 'x'. + item_type: Api::Type::String From 086a67cdcb829a792e60b2f8858e3f4f71f6b278 Mon Sep 17 00:00:00 2001 From: Sean McGivern <27fv8yygye@snkmail.com> Date: Wed, 30 Aug 2023 16:22:00 +0100 Subject: [PATCH 017/476] Make SQL database flags a set (#8118) Co-authored-by: Cameron Thornton --- .../sql/resource_sql_database_instance.go.erb | 35 ++++----- .../resource_sql_database_instance_test.go | 72 +++++++++++++++++++ mmv1/third_party/tgc/sql_database_instance.go | 2 +- 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb index 28004b4c275d..90f7ef577212 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb +++ b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb @@ -46,6 +46,21 @@ var sqlDatabaseAuthorizedNetWorkSchemaElem *schema.Resource = &schema.Resource{ }, } +var sqlDatabaseFlagSchemaElem *schema.Resource = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "value": { + Type: schema.TypeString, + Required: true, + Description: `Value of the flag.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: `Name of the flag.`, + }, + }, +} + var ( backupConfigurationKeys = []string{ "settings.0.backup_configuration.0.binary_log_enabled", @@ -362,22 +377,10 @@ is set to true. Defaults to ZONAL.`, Description: `The name of server instance collation.`, }, "database_flags": { - Type: schema.TypeList, + Type: schema.TypeSet, Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "value": { - Type: schema.TypeString, - Required: true, - Description: `Value of the flag.`, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: `Name of the flag.`, - }, - }, - }, + Set: schema.HashResource(sqlDatabaseFlagSchemaElem), + Elem: sqlDatabaseFlagSchemaElem, }, "disk_autoresize": { Type: schema.TypeBool, @@ -1261,7 +1264,7 @@ func expandSqlDatabaseInstanceSettings(configured []interface{}, databaseVersion DeletionProtectionEnabled: _settings["deletion_protection_enabled"].(bool), UserLabels: tpgresource.ConvertStringMap(_settings["user_labels"].(map[string]interface{})), BackupConfiguration: expandBackupConfiguration(_settings["backup_configuration"].([]interface{})), - DatabaseFlags: expandDatabaseFlags(_settings["database_flags"].([]interface{})), + DatabaseFlags: expandDatabaseFlags(_settings["database_flags"].(*schema.Set).List()), IpConfiguration: expandIpConfiguration(_settings["ip_configuration"].([]interface{}), databaseVersion), LocationPreference: expandLocationPreference(_settings["location_preference"].([]interface{})), MaintenanceWindow: expandMaintenanceWindow(_settings["maintenance_window"].([]interface{})), diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go index 7f43e53d8870..64607beb5cb0 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go +++ b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go @@ -1671,6 +1671,34 @@ func TestAccSqlDatabaseInstance_Timezone(t *testing.T) { }) } +func TestAccSqlDatabaseInstance_updateDifferentFlagOrder(t *testing.T) { + t.Parallel() + + instance := "tf-test-" + acctest.RandString(t, 10) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testGoogleSqlDatabaseInstance_flags(instance), + }, + { + ResourceName: "google_sql_database_instance.instance", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testGoogleSqlDatabaseInstance_flags_update(instance), + PlanOnly: true, + ExpectNonEmptyPlan: false, + }, + }, + }) +} + func TestAccSqlDatabaseInstance_sqlMysqlInstancePvpExample(t *testing.T) { t.Parallel() @@ -3830,6 +3858,50 @@ func checkInstanceTypeIsPresent(resourceName string) func(*terraform.State) erro } } +func testGoogleSqlDatabaseInstance_flags(instance string) string { + return fmt.Sprintf(` +resource "google_sql_database_instance" "instance" { + name = "%s" + region = "us-central1" + database_version = "MYSQL_5_7" + deletion_protection = false + settings { + tier = "db-f1-micro" + + database_flags { + name = "character_set_server" + value = "utf8mb4" + } + database_flags { + name = "auto_increment_increment" + value = "2" + } + } +}`, instance) +} + +func testGoogleSqlDatabaseInstance_flags_update(instance string) string { + return fmt.Sprintf(` +resource "google_sql_database_instance" "instance" { + name = "%s" + region = "us-central1" + database_version = "MYSQL_5_7" + deletion_protection = false + settings { + tier = "db-f1-micro" + + database_flags { + name = "auto_increment_increment" + value = "2" + } + database_flags { + name = "character_set_server" + value = "utf8mb4" + } + } +}`, instance) +} + func testGoogleSqlDatabaseInstance_readReplica(instance string) string { return fmt.Sprintf(` resource "google_sql_database_instance" "master" { diff --git a/mmv1/third_party/tgc/sql_database_instance.go b/mmv1/third_party/tgc/sql_database_instance.go index 9eba9d623725..add0a43f459c 100644 --- a/mmv1/third_party/tgc/sql_database_instance.go +++ b/mmv1/third_party/tgc/sql_database_instance.go @@ -110,7 +110,7 @@ func expandSqlDatabaseInstanceSettings(configured []interface{}, secondGen bool) PricingPlan: _settings["pricing_plan"].(string), UserLabels: tpgresource.ConvertStringMap(_settings["user_labels"].(map[string]interface{})), BackupConfiguration: expandBackupConfiguration(_settings["backup_configuration"].([]interface{})), - DatabaseFlags: expandDatabaseFlags(_settings["database_flags"].([]interface{})), + DatabaseFlags: expandDatabaseFlags(_settings["database_flags"].(*schema.Set).List()), IpConfiguration: expandIpConfiguration(_settings["ip_configuration"].([]interface{})), LocationPreference: expandLocationPreference(_settings["location_preference"].([]interface{})), MaintenanceWindow: expandMaintenanceWindow(_settings["maintenance_window"].([]interface{})), From 415c90dfc305e52b79c5a4f78366760d6a9a3bc0 Mon Sep 17 00:00:00 2001 From: pengq-google Date: Wed, 30 Aug 2023 15:05:49 -0400 Subject: [PATCH 018/476] Mark `num_finite_buckets` required for cloud logging metric bucket_options (#8780) Co-authored-by: Cameron Thornton --- mmv1/products/logging/Metric.yaml | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/mmv1/products/logging/Metric.yaml b/mmv1/products/logging/Metric.yaml index 030758a8465d..98b154070d22 100644 --- a/mmv1/products/logging/Metric.yaml +++ b/mmv1/products/logging/Metric.yaml @@ -206,28 +206,19 @@ properties: properties: - !ruby/object:Api::Type::Integer name: numFiniteBuckets - at_least_one_of: - - bucket_options.0.linear_buckets.0.num_finite_buckets - - bucket_options.0.linear_buckets.0.width - - bucket_options.0.linear_buckets.0.offset description: | Must be greater than 0. + required: true - !ruby/object:Api::Type::Double name: width - at_least_one_of: - - bucket_options.0.linear_buckets.0.num_finite_buckets - - bucket_options.0.linear_buckets.0.width - - bucket_options.0.linear_buckets.0.offset description: | Must be greater than 0. + required: true - !ruby/object:Api::Type::Double name: offset - at_least_one_of: - - bucket_options.0.linear_buckets.0.num_finite_buckets - - bucket_options.0.linear_buckets.0.width - - bucket_options.0.linear_buckets.0.offset description: | Lower bound of the first bucket. + required: true - !ruby/object:Api::Type::NestedObject name: exponentialBuckets at_least_one_of: @@ -240,28 +231,19 @@ properties: properties: - !ruby/object:Api::Type::Integer name: numFiniteBuckets - at_least_one_of: - - bucket_options.0.exponential_buckets.0.num_finite_buckets - - bucket_options.0.exponential_buckets.0.growth_factor - - bucket_options.0.exponential_buckets.0.scale description: | Must be greater than 0. + required: true - !ruby/object:Api::Type::Double name: growthFactor - at_least_one_of: - - bucket_options.0.exponential_buckets.0.num_finite_buckets - - bucket_options.0.exponential_buckets.0.growth_factor - - bucket_options.0.exponential_buckets.0.scale description: | Must be greater than 1. + required: true - !ruby/object:Api::Type::Double name: scale - at_least_one_of: - - bucket_options.0.exponential_buckets.0.num_finite_buckets - - bucket_options.0.exponential_buckets.0.growth_factor - - bucket_options.0.exponential_buckets.0.scale description: | Must be greater than 0. + required: true - !ruby/object:Api::Type::NestedObject name: explicitBuckets at_least_one_of: From 2afc9e6d3881a4216be6da96c5f64ba3e75af067 Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:57:48 -0700 Subject: [PATCH 019/476] Remove default value for rule.rate_limit_options.encorce_on_key on resource google_compute_security_policy (#8804) --- .../services/compute/resource_compute_security_policy.go.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb index a96ca1fe6a8e..4b82ac79182b 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb @@ -268,7 +268,6 @@ func ResourceComputeSecurityPolicy() *schema.Resource { "enforce_on_key": { Type: schema.TypeString, Optional: true, - Default: "ALL", Description: `Determines the key to enforce the rateLimitThreshold on`, ValidateFunc: validation.StringInSlice([]string{"ALL", "IP", "HTTP_HEADER", "XFF_IP", "HTTP_COOKIE", "HTTP_PATH", "SNI", "REGION_CODE", ""}, false), }, From ae21b64e00316f10680dc0ea77166be283f4b32d Mon Sep 17 00:00:00 2001 From: Nick Elliot Date: Fri, 1 Sep 2023 14:00:04 -0700 Subject: [PATCH 020/476] Display default provider values at plan-time (#8569) --- mmv1/api/resource.rb | 5 + mmv1/products/compute/Autoscaler.yaml | 1 + .../compute/DiskResourcePolicyAttachment.yaml | 1 + .../compute/NetworkEndpointGroup.yaml | 1 + mmv1/products/compute/PerInstanceConfig.yaml | 1 + mmv1/products/compute/RegionAutoscaler.yaml | 1 + mmv1/products/compute/ResourcePolicy.yaml | 1 + mmv1/products/compute/ServiceAttachment.yaml | 1 + mmv1/products/redis/Instance.yaml | 2 + mmv1/templates/terraform/resource.erb | 22 +- .../resource_app_engine_application.go | 1 + .../bigquery/resource_bigquery_table.go | 1 + .../bigtable/resource_bigtable_instance.go | 1 + .../bigtable/resource_bigtable_table.go | 4 + .../resource_cloudfunctions_function.go | 6 + .../resource_composer_environment.go.erb | 6 + .../resource_compute_attached_disk.go.erb | 6 + .../compute/resource_compute_instance.go.erb | 2 + ...urce_compute_instance_from_template.go.erb | 6 +- .../resource_compute_instance_group.go.erb | 6 + ...urce_compute_instance_group_manager.go.erb | 5 + .../resource_compute_instance_template.go.erb | 1 + ...ompute_project_default_network_tier.go.erb | 5 + .../resource_compute_project_metadata.go.erb | 5 + ...ource_compute_project_metadata_item.go.erb | 5 + ...mpute_region_instance_group_manager.go.erb | 6 + ...ce_compute_region_instance_template.go.erb | 2 + .../resource_compute_router_interface.go.erb | 6 + .../resource_compute_security_policy.go.erb | 6 +- ..._compute_shared_vpc_service_project.go.erb | 5 + .../resource_compute_target_pool.go.erb | 6 + .../resource_usage_export_bucket.go.erb | 5 + .../resource_container_node_pool.go.erb | 1 + .../resource_container_registry.go | 5 + .../dataproc/resource_dataproc_cluster.go.erb | 5 + .../dataproc/resource_dataproc_job.go.erb | 5 + .../resource_dialogflow_cx_environment.go | 5 + .../resource_dialogflow_cx_version.go | 5 + .../services/dns/resource_dns_record_set.go | 5 + .../logging/resource_logging_bucket_config.go | 4 + .../resource_monitoring_dashboard.go | 5 + ...resource_os_config_os_policy_assignment.go | 5 + ...resource_google_project_iam_custom_role.go | 5 + .../resource_google_project_service.go | 5 + .../resource_google_service_account.go | 4 + .../resource_project_service_identity.go.erb | 5 + .../resource_runtimeconfig_config.go.erb | 5 + .../resource_runtimeconfig_variable.go.erb | 5 + ...le_service_networking_peered_dns_domain.go | 5 + .../sql/resource_sql_database_instance.go.erb | 1 + .../services/sql/resource_sql_ssl_cert.go | 5 + .../services/sql/resource_sql_user.go | 5 + .../resource_storage_transfer_job.go | 5 + .../terraform/tpgresource/utils.go | 93 +++ .../provider_versionfive_upgrade_test.go.erb | 646 ++++++++++++++++++ tpgtools/overrides/apikeys/beta/key.yaml | 4 + tpgtools/overrides/apikeys/key.yaml | 4 + .../bigqueryreservation/assignment.yaml | 4 + .../bigqueryreservation/beta/assignment.yaml | 4 + .../cloudbuild/beta/worker_pool.yaml | 4 + .../overrides/cloudbuild/worker_pool.yaml | 4 + .../cloudbuildv2/beta/connection.yaml | 4 + .../cloudbuildv2/beta/repository.yaml | 4 + .../overrides/cloudbuildv2/connection.yaml | 4 + .../overrides/cloudbuildv2/repository.yaml | 4 + .../clouddeploy/beta/delivery_pipeline.yaml | 4 + .../overrides/clouddeploy/beta/target.yaml | 4 + .../clouddeploy/delivery_pipeline.yaml | 4 + tpgtools/overrides/clouddeploy/target.yaml | 4 + .../compute/beta/firewall_policy.yaml | 4 + .../beta/firewall_policy_association.yaml | 4 + .../compute/beta/firewall_policy_rule.yaml | 4 + .../compute/beta/network_firewall_policy.yaml | 5 + .../network_firewall_policy_association.yaml | 5 + .../beta/network_firewall_policy_rule.yaml | 5 + .../overrides/compute/firewall_policy.yaml | 4 + .../compute/firewall_policy_association.yaml | 4 + .../compute/firewall_policy_rule.yaml | 4 + .../compute/network_firewall_policy.yaml | 5 + .../network_firewall_policy_association.yaml | 5 + .../compute/network_firewall_policy_rule.yaml | 5 + .../overrides/containeraws/beta/cluster.yaml | 4 + .../containeraws/beta/node_pool.yaml | 4 + tpgtools/overrides/containeraws/cluster.yaml | 4 + .../overrides/containeraws/node_pool.yaml | 4 + .../containerazure/azure_client.yaml | 4 + .../containerazure/beta/azure_client.yaml | 4 + .../containerazure/beta/cluster.yaml | 6 +- .../containerazure/beta/node_pool.yaml | 4 + .../overrides/containerazure/cluster.yaml | 4 + .../overrides/containerazure/node_pool.yaml | 4 + tpgtools/overrides/dataplex/asset.yaml | 4 + tpgtools/overrides/dataplex/beta/asset.yaml | 4 + tpgtools/overrides/dataplex/beta/lake.yaml | 4 + tpgtools/overrides/dataplex/beta/zone.yaml | 4 + tpgtools/overrides/dataplex/lake.yaml | 4 + tpgtools/overrides/dataplex/zone.yaml | 4 + .../dataproc/beta/workflow_template.yaml | 4 + .../overrides/dataproc/workflow_template.yaml | 4 + tpgtools/overrides/eventarc/beta/channel.yaml | 4 + .../eventarc/beta/google_channel_config.yaml | 4 + tpgtools/overrides/eventarc/beta/trigger.yaml | 5 +- tpgtools/overrides/eventarc/channel.yaml | 4 + .../eventarc/google_channel_config.yaml | 4 + tpgtools/overrides/eventarc/trigger.yaml | 4 + .../overrides/firebaserules/beta/release.yaml | 4 + .../overrides/firebaserules/beta/ruleset.yaml | 4 + tpgtools/overrides/firebaserules/release.yaml | 4 + tpgtools/overrides/firebaserules/ruleset.yaml | 4 + .../gkehub/beta/feature_membership.yaml | 6 +- .../networkconnectivity/beta/hub.yaml | 4 + .../networkconnectivity/beta/spoke.yaml | 4 + .../overrides/networkconnectivity/hub.yaml | 4 + .../overrides/networkconnectivity/spoke.yaml | 4 + .../privateca/beta/certificate_template.yaml | 4 + .../privateca/certificate_template.yaml | 4 + .../recaptchaenterprise/beta/key.yaml | 4 + .../overrides/recaptchaenterprise/key.yaml | 4 + 118 files changed, 1223 insertions(+), 6 deletions(-) create mode 100644 mmv1/third_party/terraform/utils/provider_versionfive_upgrade_test.go.erb diff --git a/mmv1/api/resource.rb b/mmv1/api/resource.rb index 267b2d91115f..0321f88f89f5 100644 --- a/mmv1/api/resource.rb +++ b/mmv1/api/resource.rb @@ -217,6 +217,10 @@ module Properties # public ca external account keys attr_reader :skip_read + # Set to true for resources that wish to disable automatic generation of default provider + # value customdiff functions + attr_reader :skip_default_cdiff + # This enables resources that get their project via a reference to a different resource # instead of a project field to use User Project Overrides attr_reader :supports_indirect_user_project_override @@ -322,6 +326,7 @@ def validate check :migrate_state, type: String check :skip_delete, type: :boolean, default: false check :skip_read, type: :boolean, default: false + check :skip_default_cdiff, type: :boolean, default: false check :supports_indirect_user_project_override, type: :boolean, default: false check :legacy_long_form_project, type: :boolean, default: false check :read_error_transform, type: String diff --git a/mmv1/products/compute/Autoscaler.yaml b/mmv1/products/compute/Autoscaler.yaml index 8c66621727e9..e4480401284e 100644 --- a/mmv1/products/compute/Autoscaler.yaml +++ b/mmv1/products/compute/Autoscaler.yaml @@ -84,6 +84,7 @@ parameters: URL of the zone where the instance group resides. required: false immutable: true + ignore_read: true default_from_api: true custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.erb' properties: diff --git a/mmv1/products/compute/DiskResourcePolicyAttachment.yaml b/mmv1/products/compute/DiskResourcePolicyAttachment.yaml index c2cbb0524deb..0926037d8e30 100644 --- a/mmv1/products/compute/DiskResourcePolicyAttachment.yaml +++ b/mmv1/products/compute/DiskResourcePolicyAttachment.yaml @@ -77,6 +77,7 @@ parameters: description: 'A reference to the zone where the disk resides.' required: false url_param_only: true + ignore_read: true default_from_api: true properties: - !ruby/object:Api::Type::String diff --git a/mmv1/products/compute/NetworkEndpointGroup.yaml b/mmv1/products/compute/NetworkEndpointGroup.yaml index 9e849d2b3f76..529ebb2fab35 100644 --- a/mmv1/products/compute/NetworkEndpointGroup.yaml +++ b/mmv1/products/compute/NetworkEndpointGroup.yaml @@ -78,6 +78,7 @@ parameters: Zone where the network endpoint group is located. required: false default_from_api: true + ignore_read: true custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.erb' properties: - !ruby/object:Api::Type::String diff --git a/mmv1/products/compute/PerInstanceConfig.yaml b/mmv1/products/compute/PerInstanceConfig.yaml index 57c1b8bc3300..5ebfb93a4cfa 100644 --- a/mmv1/products/compute/PerInstanceConfig.yaml +++ b/mmv1/products/compute/PerInstanceConfig.yaml @@ -124,6 +124,7 @@ parameters: url_param_only: true immutable: true ignore_read: true + default_from_api: true - !ruby/object:Api::Type::ResourceRef name: 'instanceGroupManager' resource: 'InstanceGroupManager' diff --git a/mmv1/products/compute/RegionAutoscaler.yaml b/mmv1/products/compute/RegionAutoscaler.yaml index e68955cf3728..3783b308a3be 100644 --- a/mmv1/products/compute/RegionAutoscaler.yaml +++ b/mmv1/products/compute/RegionAutoscaler.yaml @@ -65,6 +65,7 @@ parameters: required: false immutable: true default_from_api: true + ignore_read: true custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.erb' properties: - !ruby/object:Api::Type::Time diff --git a/mmv1/products/compute/ResourcePolicy.yaml b/mmv1/products/compute/ResourcePolicy.yaml index 2fc5f561273e..8e645187a41e 100644 --- a/mmv1/products/compute/ResourcePolicy.yaml +++ b/mmv1/products/compute/ResourcePolicy.yaml @@ -85,6 +85,7 @@ parameters: description: Region where resource policy resides. immutable: true required: false + ignore_read: true default_from_api: true custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.erb' properties: diff --git a/mmv1/products/compute/ServiceAttachment.yaml b/mmv1/products/compute/ServiceAttachment.yaml index a795f7d97a98..427ef1eb1fc8 100644 --- a/mmv1/products/compute/ServiceAttachment.yaml +++ b/mmv1/products/compute/ServiceAttachment.yaml @@ -93,6 +93,7 @@ parameters: required: false immutable: true default_from_api: true + ignore_read: true custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.erb' properties: - !ruby/object:Api::Type::String diff --git a/mmv1/products/redis/Instance.yaml b/mmv1/products/redis/Instance.yaml index eaab27ffdb55..b232ae4e69bd 100644 --- a/mmv1/products/redis/Instance.yaml +++ b/mmv1/products/redis/Instance.yaml @@ -28,6 +28,7 @@ timeouts: !ruby/object:Api::Timeouts update_minutes: 20 delete_minutes: 20 autogen_async: true +skip_default_cdiff: true custom_code: !ruby/object:Provider::Terraform::CustomCode encoder: templates/terraform/encoders/redis_location_id_for_fallback_zone.go.erb decoder: templates/terraform/decoders/redis_instance.go.erb @@ -35,6 +36,7 @@ custom_code: !ruby/object:Provider::Terraform::CustomCode constants: templates/terraform/constants/redis_instance.go custom_diff: [ 'customdiff.ForceNewIfChange("redis_version", isRedisVersionDecreasing)', + 'tpgresource.DefaultProviderProject', ] examples: - !ruby/object:Provider::Terraform::Examples diff --git a/mmv1/templates/terraform/resource.erb b/mmv1/templates/terraform/resource.erb index 4306de057c7a..f24f763b02f3 100644 --- a/mmv1/templates/terraform/resource.erb +++ b/mmv1/templates/terraform/resource.erb @@ -65,6 +65,7 @@ import ( client_name_lower = client_name.downcase has_project = object.base_url.include?('{{project}}') || (object.create_url && object.create_url.include?('{{project}}')) has_region = object.base_url.include?('{{region}}') && object.parameters.any?{ |p| p.name == 'region' && p.ignore_read } + has_zone = object.base_url.include?('{{zone}}') && object.parameters.any?{ |p| p.name == 'zone' && p.ignore_read } # In order of preference, use TF override, # general defined timeouts, or default Timeouts timeouts = object.timeouts @@ -113,7 +114,7 @@ func Resource<%= resource_name -%>() *schema.Resource { <% end -%> }, <% end -%> -<% if object.custom_diff.any? || object.settable_properties.any? {|p| p.unordered_list}-%> +<% if ((has_project || has_region || has_zone) && !object.skip_default_cdiff) || object.custom_diff.any? || object.settable_properties.any? {|p| p.unordered_list}-%> CustomizeDiff: customdiff.All( <% if object.settable_properties.any? {|p| p.unordered_list} -%> <%= @@ -126,6 +127,15 @@ func Resource<%= resource_name -%>() *schema.Resource { <% for cdiff in object.custom_diff-%> <%= cdiff%>, <% end -%> +<% end -%> +<% if has_project && !object.skip_default_cdiff -%> + tpgresource.DefaultProviderProject, +<% end -%> +<% if has_region && !object.skip_default_cdiff -%> + tpgresource.DefaultProviderRegion, +<% end -%> +<% if has_zone && !object.skip_default_cdiff -%> + tpgresource.DefaultProviderZone, <% end -%> ), <% end -%> @@ -640,6 +650,16 @@ func resource<%= resource_name -%>Read(d *schema.ResourceData, meta interface{}) } <% end -%> +<% if has_zone -%> + zone, err := tpgresource.GetZone(d, config) + if err != nil { + return err + } + if err := d.Set("zone", zone); err != nil { + return fmt.Errorf("Error reading <%= object.name -%>: %s", err) + } +<% end -%> + <% object.gettable_properties.reject{|p| p.ignore_read }.each do |prop| -%> <% if prop.flatten_object -%> // Terraform must set the top level schema field, but since this object contains collapsed properties diff --git a/mmv1/third_party/terraform/services/appengine/resource_app_engine_application.go b/mmv1/third_party/terraform/services/appengine/resource_app_engine_application.go index 0ca799ade56d..c7d631e84806 100644 --- a/mmv1/third_party/terraform/services/appengine/resource_app_engine_application.go +++ b/mmv1/third_party/terraform/services/appengine/resource_app_engine_application.go @@ -32,6 +32,7 @@ func ResourceAppEngineApplication() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, appEngineApplicationLocationIDCustomizeDiff, ), diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index 99debcd4cdd5..8116bf8834ba 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -419,6 +419,7 @@ func ResourceBigQueryTable() *schema.Resource { State: resourceBigQueryTableImport, }, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, resourceBigQueryTableSchemaCustomizeDiff, ), Schema: map[string]*schema.Schema{ diff --git a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go index 840e1be46e12..1863b8f3e8c9 100644 --- a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go +++ b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go @@ -34,6 +34,7 @@ func ResourceBigtableInstance() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, resourceBigtableInstanceClusterReorderTypeList, resourceBigtableInstanceUniqueClusterID, ), diff --git a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_table.go b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_table.go index cd5d4f334b70..22dfdb88c53f 100644 --- a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_table.go +++ b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_table.go @@ -7,6 +7,7 @@ import ( "time" "cloud.google.com/go/bigtable" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -32,6 +33,9 @@ func ResourceBigtableTable() *schema.Resource { Update: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), // ---------------------------------------------------------------------- // IMPORTANT: Do not add any additional ForceNew fields to this resource. // Destroying/recreating tables can lead to data loss for users. diff --git a/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go b/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go index 6519fa0444b5..6cf41e153ef4 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go +++ b/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function.go @@ -3,6 +3,7 @@ package cloudfunctions import ( "regexp" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -141,6 +142,11 @@ func ResourceCloudFunctionsFunction() *schema.Resource { Delete: schema.DefaultTimeout(5 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderRegion, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb b/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb index dc642a764e09..4dc1b2b86ce3 100644 --- a/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb +++ b/mmv1/third_party/terraform/services/composer/resource_composer_environment.go.erb @@ -9,6 +9,7 @@ import ( "time" "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -156,6 +157,11 @@ func ResourceComposerEnvironment() *schema.Resource { Delete: schema.DefaultTimeout(30 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderRegion, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_attached_disk.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_attached_disk.go.erb index cec13a19f1da..9725498a1f7a 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_attached_disk.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_attached_disk.go.erb @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -35,6 +36,11 @@ func ResourceComputeAttachedDisk() *schema.Resource { Delete: schema.DefaultTimeout(300 * time.Second), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderZone, + ), + Schema: map[string]*schema.Schema{ "disk": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb index 5a7eca0f7514..fdbbdc29bef8 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance.go.erb @@ -1044,6 +1044,8 @@ be from 0 to 999,999,999 inclusive.`, }, }, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderZone, customdiff.If( func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool { return d.HasChange("guest_accelerator") diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_from_template.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_from_template.go.erb index 5d624b4b797e..fc61dd0c02c5 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_from_template.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_from_template.go.erb @@ -7,6 +7,7 @@ import ( "log" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" @@ -32,7 +33,10 @@ func ResourceComputeInstanceFromTemplate() *schema.Resource { Timeouts: ResourceComputeInstance().Timeouts, Schema: computeInstanceFromTemplateSchema(), - CustomizeDiff: ResourceComputeInstance().CustomizeDiff, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ResourceComputeInstance().CustomizeDiff, + ), UseJSONNumber: true, } } diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_group.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_group.go.erb index 856c24d3b6aa..e577bf497906 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_group.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_group.go.erb @@ -12,6 +12,7 @@ import ( "google.golang.org/api/googleapi" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" <% if version == "ga" -%> @@ -36,6 +37,11 @@ func ResourceComputeInstanceGroup() *schema.Resource { Update: schema.DefaultTimeout(6 * time.Minute), Delete: schema.DefaultTimeout(6 * time.Minute), }, + + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderZone, + ), SchemaVersion: 2, MigrateState: resourceComputeInstanceGroupMigrateState, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_group_manager.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_group_manager.go.erb index ca89eddea57c..75a142685a37 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_group_manager.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_group_manager.go.erb @@ -9,6 +9,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -36,6 +37,10 @@ func ResourceComputeInstanceGroupManager() *schema.Resource { Update: schema.DefaultTimeout(15 * time.Minute), Delete: schema.DefaultTimeout(15 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderZone, + ), Schema: map[string]*schema.Schema{ "base_instance_name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb index 1aa43d6df564..d44091b50ece 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb @@ -62,6 +62,7 @@ func ResourceComputeInstanceTemplate() *schema.Resource { }, SchemaVersion: 1, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, resourceComputeInstanceTemplateSourceImageCustomizeDiff, resourceComputeInstanceTemplateScratchDiskCustomizeDiff, resourceComputeInstanceTemplateBootDiskCustomizeDiff, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_project_default_network_tier.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_project_default_network_tier.go.erb index 2b838cd1bcad..3f1830c4c210 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_project_default_network_tier.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_project_default_network_tier.go.erb @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" <% if version == "ga" -%> @@ -34,6 +35,10 @@ func ResourceComputeProjectDefaultNetworkTier() *schema.Resource { Create: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + SchemaVersion: 0, Schema: map[string]*schema.Schema{ diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata.go.erb index 8186762eb938..8e8560b592f2 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata.go.erb @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" <% if version == "ga" -%> @@ -33,6 +34,10 @@ func ResourceComputeProjectMetadata() *schema.Resource { Delete: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + SchemaVersion: 0, Schema: map[string]*schema.Schema{ diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata_item.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata_item.go.erb index 5cf62dc29590..957476bb24fb 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata_item.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_project_metadata_item.go.erb @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" <% if version == "ga" -%> @@ -35,6 +36,10 @@ func ResourceComputeProjectMetadataItem() *schema.Resource { State: schema.ImportStatePassthrough, }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "key": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_group_manager.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_group_manager.go.erb index 9ac36c5455a8..d95ed976e020 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_group_manager.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_group_manager.go.erb @@ -9,6 +9,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -37,6 +38,11 @@ func ResourceComputeRegionInstanceGroupManager() *schema.Resource { Delete: schema.DefaultTimeout(15 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderRegion, + ), + Schema: map[string]*schema.Schema{ "base_instance_name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb index 2050ede84d0c..ed8687a5271f 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb @@ -36,6 +36,8 @@ func ResourceComputeRegionInstanceTemplate() *schema.Resource { }, SchemaVersion: 1, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderRegion, resourceComputeInstanceTemplateSourceImageCustomizeDiff, resourceComputeInstanceTemplateScratchDiskCustomizeDiff, resourceComputeInstanceTemplateBootDiskCustomizeDiff, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_router_interface.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_router_interface.go.erb index b8f48d98cffc..807a9c443d4d 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_router_interface.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_router_interface.go.erb @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "google.golang.org/api/googleapi" @@ -35,6 +36,11 @@ func ResourceComputeRouterInterface() *schema.Resource { Delete: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderRegion, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb index 4b82ac79182b..1d2c67fb7ab4 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_security_policy.go.erb @@ -12,6 +12,7 @@ import ( "time" "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -35,7 +36,10 @@ func ResourceComputeSecurityPolicy() *schema.Resource { Importer: &schema.ResourceImporter{ State: resourceSecurityPolicyStateImporter, }, - CustomizeDiff: rulesCustomizeDiff, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + rulesCustomizeDiff, + ), Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(8 * time.Minute), diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_shared_vpc_service_project.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_shared_vpc_service_project.go.erb index 2ce95299eb93..3f5f9d7f74d2 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_shared_vpc_service_project.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_shared_vpc_service_project.go.erb @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "google.golang.org/api/googleapi" @@ -36,6 +37,10 @@ func ResourceComputeSharedVpcServiceProject() *schema.Resource { Delete: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "host_project": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_target_pool.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_target_pool.go.erb index 7a0bb638024f..ceb79c114082 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_target_pool.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_target_pool.go.erb @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "google.golang.org/api/googleapi" @@ -39,6 +40,11 @@ func ResourceComputeTargetPool() *schema.Resource { Delete: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + tpgresource.DefaultProviderRegion, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/compute/resource_usage_export_bucket.go.erb b/mmv1/third_party/terraform/services/compute/resource_usage_export_bucket.go.erb index e15258a3cc79..da1205fc1dca 100644 --- a/mmv1/third_party/terraform/services/compute/resource_usage_export_bucket.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_usage_export_bucket.go.erb @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" <% if version == "ga" -%> @@ -32,6 +33,10 @@ func ResourceProjectUsageBucket() *schema.Resource { Delete: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "bucket_name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb index 9d73c6ccb416..14d7e4419cfd 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb @@ -48,6 +48,7 @@ func ResourceContainerNodePool() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, resourceNodeConfigEmptyGuestAccelerator, ), diff --git a/mmv1/third_party/terraform/services/containeranalysis/resource_container_registry.go b/mmv1/third_party/terraform/services/containeranalysis/resource_container_registry.go index f19e1389bd0b..d44bb07e105c 100644 --- a/mmv1/third_party/terraform/services/containeranalysis/resource_container_registry.go +++ b/mmv1/third_party/terraform/services/containeranalysis/resource_container_registry.go @@ -5,6 +5,7 @@ import ( "log" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -16,6 +17,10 @@ func ResourceContainerRegistry() *schema.Resource { Read: resourceContainerRegistryRead, Delete: resourceContainerRegistryDelete, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "location": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster.go.erb b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster.go.erb index 39c8bd221972..d66f2a3464f8 100644 --- a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster.go.erb +++ b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster.go.erb @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -162,6 +163,10 @@ func ResourceDataprocCluster() *schema.Resource { Delete: schema.DefaultTimeout(45 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb index d1fcd5ceb4dd..fc6c576a08c3 100644 --- a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb +++ b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_job.go.erb @@ -11,6 +11,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" "github.com/hashicorp/terraform-provider-google/google/verify" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "google.golang.org/api/dataproc/v1" @@ -30,6 +31,10 @@ func ResourceDataprocJob() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "project": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_environment.go b/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_environment.go index 086883aa0d4d..3953c21bb38d 100644 --- a/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_environment.go +++ b/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_environment.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -32,6 +33,10 @@ func ResourceDialogflowCXEnvironment() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "display_name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_version.go b/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_version.go index 980387b9eb16..98d22ff459ed 100644 --- a/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_version.go +++ b/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_version.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -33,6 +34,10 @@ func ResourceDialogflowCXVersion() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "display_name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/dns/resource_dns_record_set.go b/mmv1/third_party/terraform/services/dns/resource_dns_record_set.go index 38d53ebc4b39..4a4d90eaa5a0 100644 --- a/mmv1/third_party/terraform/services/dns/resource_dns_record_set.go +++ b/mmv1/third_party/terraform/services/dns/resource_dns_record_set.go @@ -8,6 +8,7 @@ import ( "net" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-google/google/tpgresource" @@ -81,6 +82,10 @@ func ResourceDnsRecordSet() *schema.Resource { State: resourceDnsRecordSetImportState, }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "managed_zone": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/logging/resource_logging_bucket_config.go b/mmv1/third_party/terraform/services/logging/resource_logging_bucket_config.go index 9ad5ebb08f29..923d253a74d0 100644 --- a/mmv1/third_party/terraform/services/logging/resource_logging_bucket_config.go +++ b/mmv1/third_party/terraform/services/logging/resource_logging_bucket_config.go @@ -6,6 +6,7 @@ import ( "regexp" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -105,6 +106,9 @@ func ResourceLoggingBucketConfig(parentType string, parentSpecificSchema map[str }, Schema: tpgresource.MergeSchemas(loggingBucketConfigSchema, parentSpecificSchema), UseJSONNumber: true, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), } } diff --git a/mmv1/third_party/terraform/services/monitoring/resource_monitoring_dashboard.go b/mmv1/third_party/terraform/services/monitoring/resource_monitoring_dashboard.go index b0a06770882d..aa8a0d57c5e3 100644 --- a/mmv1/third_party/terraform/services/monitoring/resource_monitoring_dashboard.go +++ b/mmv1/third_party/terraform/services/monitoring/resource_monitoring_dashboard.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -51,6 +52,10 @@ func ResourceMonitoringDashboard() *schema.Resource { Delete: schema.DefaultTimeout(4 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "dashboard_json": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/osconfig/resource_os_config_os_policy_assignment.go b/mmv1/third_party/terraform/services/osconfig/resource_os_config_os_policy_assignment.go index c3e8e143c89d..9ea349cdbce8 100644 --- a/mmv1/third_party/terraform/services/osconfig/resource_os_config_os_policy_assignment.go +++ b/mmv1/third_party/terraform/services/osconfig/resource_os_config_os_policy_assignment.go @@ -7,6 +7,7 @@ import ( "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/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -30,6 +31,10 @@ func ResourceOSConfigOSPolicyAssignment() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "instance_filter": { Type: schema.TypeList, diff --git a/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_iam_custom_role.go b/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_iam_custom_role.go index 121919258376..ef27f2aacb9a 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_iam_custom_role.go +++ b/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_iam_custom_role.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-google/google/tpgresource" @@ -23,6 +24,10 @@ func ResourceGoogleProjectIamCustomRole() *schema.Resource { State: resourceGoogleProjectIamCustomRoleImport, }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "role_id": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_service.go b/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_service.go index a24765e16f6d..94d5d4873e18 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_service.go +++ b/mmv1/third_party/terraform/services/resourcemanager/resource_google_project_service.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" tpgserviceusage "github.com/hashicorp/terraform-provider-google/google/services/serviceusage" @@ -93,6 +94,10 @@ func ResourceGoogleProjectService() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "service": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/resourcemanager/resource_google_service_account.go b/mmv1/third_party/terraform/services/resourcemanager/resource_google_service_account.go index ca67bda3b101..4ce623f56ad8 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/resource_google_service_account.go +++ b/mmv1/third_party/terraform/services/resourcemanager/resource_google_service_account.go @@ -9,6 +9,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" "github.com/hashicorp/terraform-provider-google/google/verify" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "google.golang.org/api/iam/v1" @@ -26,6 +27,9 @@ func ResourceGoogleServiceAccount() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(5 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), Schema: map[string]*schema.Schema{ "email": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/resourcemanager/resource_project_service_identity.go.erb b/mmv1/third_party/terraform/services/resourcemanager/resource_project_service_identity.go.erb index 9a22928cca5f..351fa637401c 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/resource_project_service_identity.go.erb +++ b/mmv1/third_party/terraform/services/resourcemanager/resource_project_service_identity.go.erb @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -26,6 +27,10 @@ func ResourceProjectServiceIdentity() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "service": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_config.go.erb b/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_config.go.erb index 273ec7dc010b..f0d1aa31a902 100644 --- a/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_config.go.erb +++ b/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_config.go.erb @@ -10,6 +10,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" "github.com/hashicorp/terraform-provider-google/google/verify" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" runtimeconfig "google.golang.org/api/runtimeconfig/v1beta1" ) @@ -27,6 +28,10 @@ func ResourceRuntimeconfigConfig() *schema.Resource { State: resourceRuntimeconfigConfigImport, }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_variable.go.erb b/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_variable.go.erb index fbabc5d7ee00..01c98fc45724 100644 --- a/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_variable.go.erb +++ b/mmv1/third_party/terraform/services/runtimeconfig/resource_runtimeconfig_variable.go.erb @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" runtimeconfig "google.golang.org/api/runtimeconfig/v1beta1" ) @@ -24,6 +25,10 @@ func ResourceRuntimeconfigVariable() *schema.Resource { State: resourceRuntimeconfigVariableImport, }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/servicenetworking/resource_google_service_networking_peered_dns_domain.go b/mmv1/third_party/terraform/services/servicenetworking/resource_google_service_networking_peered_dns_domain.go index 108d5d343588..bb9aba314e34 100644 --- a/mmv1/third_party/terraform/services/servicenetworking/resource_google_service_networking_peered_dns_domain.go +++ b/mmv1/third_party/terraform/services/servicenetworking/resource_google_service_networking_peered_dns_domain.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "google.golang.org/api/servicenetworking/v1" ) @@ -30,6 +31,10 @@ func ResourceGoogleServiceNetworkingPeeredDNSDomain() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "project": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb index 90f7ef577212..e8cbf9eab4b9 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb +++ b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.erb @@ -134,6 +134,7 @@ func ResourceSqlDatabaseInstance() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, customdiff.ForceNewIfChange("settings.0.disk_size", compute.IsDiskShrinkage), customdiff.ForceNewIfChange("master_instance_name", isMasterInstanceNameSet), customdiff.IfValueChange("instance_type", isReplicaPromoteRequested, checkPromoteConfigurationsAndUpdateDiff), diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_ssl_cert.go b/mmv1/third_party/terraform/services/sql/resource_sql_ssl_cert.go index 116a9b682f86..374230343810 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_ssl_cert.go +++ b/mmv1/third_party/terraform/services/sql/resource_sql_ssl_cert.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" sqladmin "google.golang.org/api/sqladmin/v1beta4" ) @@ -25,6 +26,10 @@ func ResourceSqlSslCert() *schema.Resource { Delete: schema.DefaultTimeout(10 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "common_name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_user.go b/mmv1/third_party/terraform/services/sql/resource_sql_user.go index d0ee4d85bc0b..599e55df39f7 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_user.go +++ b/mmv1/third_party/terraform/services/sql/resource_sql_user.go @@ -10,6 +10,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" sqladmin "google.golang.org/api/sqladmin/v1beta4" @@ -56,6 +57,10 @@ func ResourceSqlUser() *schema.Resource { Delete: schema.DefaultTimeout(10 * time.Minute), }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + SchemaVersion: 1, MigrateState: resourceSqlUserMigrateState, diff --git a/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go b/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go index 07b3c1dcc2b9..3e746270d10c 100644 --- a/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go +++ b/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go @@ -11,6 +11,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" "github.com/hashicorp/terraform-provider-google/google/verify" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -61,6 +62,10 @@ func ResourceStorageTransferJob() *schema.Resource { State: resourceStorageTransferJobStateImporter, }, + CustomizeDiff: customdiff.All( + tpgresource.DefaultProviderProject, + ), + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/mmv1/third_party/terraform/tpgresource/utils.go b/mmv1/third_party/terraform/tpgresource/utils.go index 3722678026c7..0d9310fafb8d 100644 --- a/mmv1/third_party/terraform/tpgresource/utils.go +++ b/mmv1/third_party/terraform/tpgresource/utils.go @@ -1,6 +1,7 @@ package tpgresource import ( + "context" "crypto/md5" "encoding/base64" "errors" @@ -18,6 +19,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" "github.com/hashicorp/errwrap" + "github.com/hashicorp/go-cty/cty" fwDiags "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -97,12 +99,49 @@ func GetProjectFromDiff(d *schema.ResourceDiff, config *transport_tpg.Config) (s if ok { return res.(string), nil } + if d.GetRawConfig().GetAttr("project") == cty.UnknownVal(cty.String) { + return res.(string), nil + } if config.Project != "" { return config.Project, nil } return "", fmt.Errorf("%s: required field is not set", "project") } +// getRegionFromDiff reads the "region" field from the given diff and falls +// back to the provider's value if not given. If the provider's value is not +// given, an error is returned. +func GetRegionFromDiff(d *schema.ResourceDiff, config *transport_tpg.Config) (string, error) { + res, ok := d.GetOk("region") + if ok { + return res.(string), nil + } + if d.GetRawConfig().GetAttr("region") == cty.UnknownVal(cty.String) { + return res.(string), nil + } + if config.Region != "" { + return config.Region, nil + } + return "", fmt.Errorf("%s: required field is not set", "region") +} + +// getZoneFromDiff reads the "zone" field from the given diff and falls +// back to the provider's value if not given. If the provider's value is not +// given, an error is returned. +func GetZoneFromDiff(d *schema.ResourceDiff, config *transport_tpg.Config) (string, error) { + res, ok := d.GetOk("zone") + if ok { + return res.(string), nil + } + if d.GetRawConfig().GetAttr("zone") == cty.UnknownVal(cty.String) { + return res.(string), nil + } + if config.Zone != "" { + return config.Zone, nil + } + return "", fmt.Errorf("%s: required field is not set", "zone") +} + func GetRouterLockName(region string, router string) string { return fmt.Sprintf("router/%s/%s", region, router) } @@ -702,3 +741,57 @@ func GetContentMd5Hash(content []byte) string { } return base64.StdEncoding.EncodeToString(h.Sum(nil)) } + +func DefaultProviderProject(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { + + config := meta.(*transport_tpg.Config) + + //project + if project := diff.Get("project"); project != nil { + project, err := GetProjectFromDiff(diff, config) + if err != nil { + return fmt.Errorf("Failed to retrieve project, pid: %s, err: %s", project, err) + } + err = diff.SetNew("project", project) + if err != nil { + return err + } + } + return nil +} + +func DefaultProviderRegion(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { + + config := meta.(*transport_tpg.Config) + //region + if region := diff.Get("region"); region != nil { + region, err := GetRegionFromDiff(diff, config) + if err != nil { + return fmt.Errorf("Failed to retrieve region, pid: %s, err: %s", region, err) + } + err = diff.SetNew("region", region) + if err != nil { + return err + } + } + + return nil +} + +func DefaultProviderZone(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { + + config := meta.(*transport_tpg.Config) + // zone + if zone := diff.Get("zone"); zone != nil { + zone, err := GetZoneFromDiff(diff, config) + if err != nil { + return fmt.Errorf("Failed to retrieve zone, pid: %s, err: %s", zone, err) + } + err = diff.SetNew("zone", zone) + if err != nil { + return err + } + } + + return nil +} diff --git a/mmv1/third_party/terraform/utils/provider_versionfive_upgrade_test.go.erb b/mmv1/third_party/terraform/utils/provider_versionfive_upgrade_test.go.erb new file mode 100644 index 000000000000..161ec6ccf34d --- /dev/null +++ b/mmv1/third_party/terraform/utils/provider_versionfive_upgrade_test.go.erb @@ -0,0 +1,646 @@ +<% autogen_exception -%> +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestProvider_versionfive_upgrade(t *testing.T) { + acctest.SkipIfVcr(t) + t.Parallel() + + org := envvar.GetTestOrgFromEnv(t) + billingId := envvar.GetTestBillingAccountFromEnv(t) + project := fmt.Sprintf("tf-test-%d", acctest.RandInt(t)) + + name1 := fmt.Sprintf("tf-test-%d", acctest.RandInt(t)) + name2 := fmt.Sprintf("tf-test-%d", acctest.RandInt(t)) + name3 := fmt.Sprintf("tf-test-%d", acctest.RandInt(t)) + name4 := fmt.Sprintf("tf-test-%d", acctest.RandInt(t)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + Steps: []resource.TestStep{ + { + ExternalProviders: map[string]resource.ExternalProvider{ + "google": { + VersionConstraint: "4.80.0", + Source: "hashicorp/google-beta", + }, + }, + Config: testProvider_versionfive_upgrades(project, org, billingId, name1, name2, name3, name4), + }, + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Config: testProvider_versionfive_upgrades(project, org, billingId, name1, name2, name3, name4), + PlanOnly: true, + }, + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + ResourceName: "google_data_fusion_instance.unset", + ImportState: true, + ImportStateVerify: true, + }, + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + ResourceName: "google_data_fusion_instance.set", + ImportState: true, + ImportStateVerify: true, + }, + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + ResourceName: "google_data_fusion_instance.reference", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestProvider_versionfive_ignorereads_upgrade(t *testing.T) { + acctest.SkipIfVcr(t) + t.Parallel() + + var itName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + var tpName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + var igmName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + var autoscalerName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + + diskName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + policyName := fmt.Sprintf("tf-test-policy-%s", acctest.RandString(t, 10)) + + endpointContext := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + var itNameRegion = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + var tpNameRegion = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + var igmNameRegion = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)) + var autoscalerNameRegion = fmt.Sprintf("tf-test-region-autoscaler-%s", acctest.RandString(t, 10)) + + policyContext := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + attachmentContext := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + CheckDestroy: resource.ComposeTestCheckFunc(testAccCheckComputeResourcePolicyDestroyProducer(t), + testAccCheckComputeRegionAutoscalerDestroyProducer(t), + testAccCheckComputeNetworkEndpointGroupDestroyProducer(t), + testAccCheckComputeAutoscalerDestroyProducer(t), + ), + Steps: []resource.TestStep{ + { + ExternalProviders: map[string]resource.ExternalProvider{ + "google": { + VersionConstraint: "4.80.0", + Source: "hashicorp/google-beta", + }, + }, + Config: testProvider_versionfive_upgrades_ignorereads(itName, tpName, igmName, autoscalerName, diskName, policyName, + itNameRegion, tpNameRegion, igmNameRegion, autoscalerNameRegion, endpointContext, + policyContext, attachmentContext), + }, + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Config: testProvider_versionfive_upgrades_ignorereads(itName, tpName, igmName, autoscalerName, diskName, policyName, + itNameRegion, tpNameRegion, igmNameRegion, autoscalerNameRegion, endpointContext, + policyContext, attachmentContext), + PlanOnly: true, + }, + }, + }) +} + +func testProvider_versionfive_upgrades(project, org, billing, name1, name2, name3, name4 string) string { + return fmt.Sprintf(` +resource "google_project" "host" { + project_id = "%s" + name = "%s" + org_id = "%s" + billing_account = "%s" +} + +resource "google_project_service" "dfapi" { + project = google_project.host.project_id + service = "datafusion.googleapis.com" + + disable_dependent_services = false +} + +resource "google_data_fusion_instance" "unset" { + name = "%s" + type = "BASIC" + options = { + prober_test_run = "true" + } +} + +resource "google_data_fusion_instance" "set" { + name = "%s" + region = "us-west1" + type = "BASIC" + options = { + prober_test_run = "true" + } +} + +resource "google_data_fusion_instance" "reference" { + project = google_project.host.project_id + name = "%s" + type = "DEVELOPER" + options = { + prober_test_run = "true" + } + zone = "us-west1-a" + depends_on = [ + google_project_service.dfapi + ] +} + +resource "google_redis_instance" "overridewithnonstandardlogic" { + name = "%s" + memory_size_gb = 1 + location_id = "us-south1-a" +} + + +`, project, project, org, billing, name1, name2, name3, name4) +} + +func testProvider_versionfive_upgrades_ignorereads(itName, tpName, igmName, autoscalerName, diskName, policyName, itNameRegion, tpNameRegion, igmNameRegion, autoscalerNameRegion string, endpointContext, policyContext, attachmentContext map[string]interface{}) string { + return testAccComputeAutoscaler_basic(itName, tpName, igmName, autoscalerName) + + testAccComputeDiskResourcePolicyAttachment_basic(diskName, policyName) + + testAccComputeNetworkEndpointGroup_networkEndpointGroup(endpointContext) + + testAccComputeRegionAutoscaler_basic(itNameRegion, tpNameRegion, igmNameRegion, autoscalerNameRegion) + + testAccComputeResourcePolicy_resourcePolicyBasicExample(policyContext) + + testAccComputeServiceAttachment_serviceAttachmentBasicExample(attachmentContext) +} + +// need to make copies of all the respective resource functions within here as *_test.go files can not be imported +// checkdestroys +func testAccCheckComputeResourcePolicyDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_resource_policy" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/resourcePolicies/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("ComputeResourcePolicy still exists at %s", url) + } + } + + return nil + } +} + +func testAccCheckComputeRegionAutoscalerDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_region_autoscaler" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/autoscalers/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("ComputeRegionAutoscaler still exists at %s", url) + } + } + + return nil + } +} + +func testAccCheckComputeNetworkEndpointGroupDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_network_endpoint_group" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/networkEndpointGroups/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("ComputeNetworkEndpointGroup still exists at %s", url) + } + } + + return nil + } +} + +func testAccCheckComputeAutoscalerDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_autoscaler" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/autoscalers/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("ComputeAutoscaler still exists at %s", url) + } + } + + return nil + } +} + +// tests +func testAccComputeAutoscaler_scaffolding(itName, tpName, igmName string) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image1" { + family = "debian-11" + project = "debian-cloud" +} + +resource "google_compute_instance_template" "foobar1" { + name = "%s" + machine_type = "e2-medium" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = data.google_compute_image.my_image1.self_link + auto_delete = true + boot = true + } + + network_interface { + network = "default" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar1" { + description = "Resource created for Terraform acceptance testing" + name = "%s" + session_affinity = "CLIENT_IP_PROTO" + region = "us-west1" +} + +resource "google_compute_instance_group_manager" "foobar1" { + description = "Terraform test instance group manager" + name = "%s" + version { + instance_template = google_compute_instance_template.foobar1.self_link + name = "primary" + } + target_pools = [google_compute_target_pool.foobar1.self_link] + base_instance_name = "foobar1" + zone = "us-west1-a" +} +`, itName, tpName, igmName) + +} + +func testAccComputeAutoscaler_basic(itName, tpName, igmName, autoscalerName string) string { + return testAccComputeAutoscaler_scaffolding(itName, tpName, igmName) + fmt.Sprintf(` +resource "google_compute_autoscaler" "foobar1" { + description = "Resource created for Terraform acceptance testing" + name = "%s" + zone = "us-west1-a" + target = google_compute_instance_group_manager.foobar1.self_link + autoscaling_policy { + max_replicas = 5 + min_replicas = 1 + cooldown_period = 60 + cpu_utilization { + target = 0.5 + } + } +} +`, autoscalerName) +} + +func testAccComputeDiskResourcePolicyAttachment_basic(diskName, policyName string) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image2" { + family = "debian-11" + project = "debian-cloud" +} + +resource "google_compute_disk" "foobar2" { + name = "%s" + image = data.google_compute_image.my_image2.self_link + size = 1000 + type = "pd-extreme" + zone = "us-west1-c" + labels = { + my-label = "my-label-value" + } + provisioned_iops = 90000 +} + +resource "google_compute_resource_policy" "foobar2" { + name = "%s" + region = "us-west1" + snapshot_schedule_policy { + schedule { + daily_schedule { + days_in_cycle = 1 + start_time = "04:00" + } + } + } +} + +resource "google_compute_disk_resource_policy_attachment" "foobar2" { + name = google_compute_resource_policy.foobar2.name + disk = google_compute_disk.foobar2.name + zone = "us-west1-c" +} +`, diskName, policyName) +} + +func testAccComputeNetworkEndpointGroup_networkEndpointGroup(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_compute_network_endpoint_group" "neg3" { + name = "tf-test-my-lb-neg%{random_suffix}" + network = google_compute_network.default3.id + default_port = "90" + zone = "us-west1-a" +} + +resource "google_compute_network" "default3" { + name = "tf-test-neg-network%{random_suffix}" + auto_create_subnetworks = true +} +`, context) +} + +func testAccComputeRegionAutoscaler_scaffolding(itName, tpName, igmName string) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image4" { + family = "debian-11" + project = "debian-cloud" +} + +resource "google_compute_instance_template" "foobar4" { + name = "%s" + machine_type = "e2-medium" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = data.google_compute_image.my_image4.self_link + auto_delete = true + boot = true + } + + network_interface { + network = "default" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar4" { + description = "Resource created for Terraform acceptance testing" + name = "%s" + session_affinity = "CLIENT_IP_PROTO" + region = "us-west1" +} + +resource "google_compute_region_instance_group_manager" "foobar4" { + description = "Terraform test instance group manager" + name = "%s" + version { + instance_template = google_compute_instance_template.foobar4.self_link + name = "primary" + } + target_pools = [google_compute_target_pool.foobar4.self_link] + base_instance_name = "tf-test-foobar4" + region = "us-west1" +} + +`, itName, tpName, igmName) +} + +func testAccComputeRegionAutoscaler_basic(itName, tpName, igmName, autoscalerName string) string { + return testAccComputeRegionAutoscaler_scaffolding(itName, tpName, igmName) + fmt.Sprintf(` +resource "google_compute_region_autoscaler" "foobar4" { + description = "Resource created for Terraform acceptance testing" + name = "%s" + region = "us-west1" + target = google_compute_region_instance_group_manager.foobar4.self_link + autoscaling_policy { + max_replicas = 5 + min_replicas = 0 + cooldown_period = 60 + cpu_utilization { + target = 0.5 + } + } +} +`, autoscalerName) +} + +func testAccComputeResourcePolicy_resourcePolicyBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_compute_resource_policy" "foo5" { + name = "tf-test-gce-policy%{random_suffix}" + region = "us-west1" + snapshot_schedule_policy { + schedule { + daily_schedule { + days_in_cycle = 1 + start_time = "04:00" + } + } + } +} +`, context) +} + +func testAccComputeServiceAttachment_serviceAttachmentBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_compute_service_attachment" "psc_ilb_service_attachment6" { + name = "tf-test-my-psc-ilb%{random_suffix}" + region = "us-west2" + description = "A service attachment configured with Terraform" + + enable_proxy_protocol = true + connection_preference = "ACCEPT_AUTOMATIC" + nat_subnets = [google_compute_subnetwork.psc_ilb_nat6.id] + target_service = google_compute_forwarding_rule.psc_ilb_target_service6.id + reconcile_connections = true +} + +resource "google_compute_address" "psc_ilb_consumer_address6" { + name = "tf-test-psc-ilb-consumer-address%{random_suffix}" + region = "us-west2" + + subnetwork = "default" + address_type = "INTERNAL" +} + +resource "google_compute_forwarding_rule" "psc_ilb_consumer6" { + name = "tf-test-psc-ilb-consumer-forwarding-rule%{random_suffix}" + region = "us-west2" + + target = google_compute_service_attachment.psc_ilb_service_attachment6.id + load_balancing_scheme = "" # need to override EXTERNAL default when target is a service attachment + network = "default" + ip_address = google_compute_address.psc_ilb_consumer_address6.id +} + +resource "google_compute_forwarding_rule" "psc_ilb_target_service6" { + name = "tf-test-producer-forwarding-rule%{random_suffix}" + region = "us-west2" + + load_balancing_scheme = "INTERNAL" + backend_service = google_compute_region_backend_service.producer_service_backend6.id + all_ports = true + network = google_compute_network.psc_ilb_network6.name + subnetwork = google_compute_subnetwork.psc_ilb_producer_subnetwork6.name +} + +resource "google_compute_region_backend_service" "producer_service_backend6" { + name = "tf-test-producer-service%{random_suffix}" + region = "us-west2" + + health_checks = [google_compute_health_check.producer_service_health_check6.id] +} + +resource "google_compute_health_check" "producer_service_health_check6" { + name = "tf-test-producer-service-health-check%{random_suffix}" + + check_interval_sec = 1 + timeout_sec = 1 + tcp_health_check { + port = "80" + } +} + +resource "google_compute_network" "psc_ilb_network6" { + name = "tf-test-psc-ilb-network%{random_suffix}" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "psc_ilb_producer_subnetwork6" { + name = "tf-test-psc-ilb-producer-subnetwork%{random_suffix}" + region = "us-west2" + + network = google_compute_network.psc_ilb_network6.id + ip_cidr_range = "10.0.0.0/16" +} + +resource "google_compute_subnetwork" "psc_ilb_nat6" { + name = "tf-test-psc-ilb-nat%{random_suffix}" + region = "us-west2" + + network = google_compute_network.psc_ilb_network6.id + purpose = "PRIVATE_SERVICE_CONNECT" + ip_cidr_range = "10.1.0.0/16" +} +`, context) +} diff --git a/tpgtools/overrides/apikeys/beta/key.yaml b/tpgtools/overrides/apikeys/beta/key.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/apikeys/beta/key.yaml +++ b/tpgtools/overrides/apikeys/beta/key.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/apikeys/key.yaml b/tpgtools/overrides/apikeys/key.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/apikeys/key.yaml +++ b/tpgtools/overrides/apikeys/key.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/bigqueryreservation/assignment.yaml b/tpgtools/overrides/bigqueryreservation/assignment.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/bigqueryreservation/assignment.yaml +++ b/tpgtools/overrides/bigqueryreservation/assignment.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/bigqueryreservation/beta/assignment.yaml b/tpgtools/overrides/bigqueryreservation/beta/assignment.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/bigqueryreservation/beta/assignment.yaml +++ b/tpgtools/overrides/bigqueryreservation/beta/assignment.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/cloudbuild/beta/worker_pool.yaml b/tpgtools/overrides/cloudbuild/beta/worker_pool.yaml index 4deb00daaee1..8c8073b08ca5 100644 --- a/tpgtools/overrides/cloudbuild/beta/worker_pool.yaml +++ b/tpgtools/overrides/cloudbuild/beta/worker_pool.yaml @@ -4,3 +4,7 @@ diffsuppressfunc: tpgresource.CompareResourceNames - type: EXCLUDE field: etag +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/cloudbuild/worker_pool.yaml b/tpgtools/overrides/cloudbuild/worker_pool.yaml index 4deb00daaee1..8c8073b08ca5 100644 --- a/tpgtools/overrides/cloudbuild/worker_pool.yaml +++ b/tpgtools/overrides/cloudbuild/worker_pool.yaml @@ -4,3 +4,7 @@ diffsuppressfunc: tpgresource.CompareResourceNames - type: EXCLUDE field: etag +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/cloudbuildv2/beta/connection.yaml b/tpgtools/overrides/cloudbuildv2/beta/connection.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/cloudbuildv2/beta/connection.yaml +++ b/tpgtools/overrides/cloudbuildv2/beta/connection.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/cloudbuildv2/beta/repository.yaml b/tpgtools/overrides/cloudbuildv2/beta/repository.yaml index 01ea7c579c97..8de5a79b7fc7 100644 --- a/tpgtools/overrides/cloudbuildv2/beta/repository.yaml +++ b/tpgtools/overrides/cloudbuildv2/beta/repository.yaml @@ -16,3 +16,7 @@ required: false optional: true computed: true +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/cloudbuildv2/connection.yaml b/tpgtools/overrides/cloudbuildv2/connection.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/cloudbuildv2/connection.yaml +++ b/tpgtools/overrides/cloudbuildv2/connection.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/cloudbuildv2/repository.yaml b/tpgtools/overrides/cloudbuildv2/repository.yaml index 01ea7c579c97..8de5a79b7fc7 100644 --- a/tpgtools/overrides/cloudbuildv2/repository.yaml +++ b/tpgtools/overrides/cloudbuildv2/repository.yaml @@ -16,3 +16,7 @@ required: false optional: true computed: true +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/clouddeploy/beta/delivery_pipeline.yaml b/tpgtools/overrides/clouddeploy/beta/delivery_pipeline.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/clouddeploy/beta/delivery_pipeline.yaml +++ b/tpgtools/overrides/clouddeploy/beta/delivery_pipeline.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/clouddeploy/beta/target.yaml b/tpgtools/overrides/clouddeploy/beta/target.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/clouddeploy/beta/target.yaml +++ b/tpgtools/overrides/clouddeploy/beta/target.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/clouddeploy/delivery_pipeline.yaml b/tpgtools/overrides/clouddeploy/delivery_pipeline.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/clouddeploy/delivery_pipeline.yaml +++ b/tpgtools/overrides/clouddeploy/delivery_pipeline.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/clouddeploy/target.yaml b/tpgtools/overrides/clouddeploy/target.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/clouddeploy/target.yaml +++ b/tpgtools/overrides/clouddeploy/target.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/beta/firewall_policy.yaml b/tpgtools/overrides/compute/beta/firewall_policy.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/compute/beta/firewall_policy.yaml +++ b/tpgtools/overrides/compute/beta/firewall_policy.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/beta/firewall_policy_association.yaml b/tpgtools/overrides/compute/beta/firewall_policy_association.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/compute/beta/firewall_policy_association.yaml +++ b/tpgtools/overrides/compute/beta/firewall_policy_association.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/beta/firewall_policy_rule.yaml b/tpgtools/overrides/compute/beta/firewall_policy_rule.yaml index e743d253be12..dc91e4f5a9d5 100644 --- a/tpgtools/overrides/compute/beta/firewall_policy_rule.yaml +++ b/tpgtools/overrides/compute/beta/firewall_policy_rule.yaml @@ -2,3 +2,7 @@ field: target_resources details: diffsuppressfunc: tpgresource.CompareSelfLinkOrResourceName +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/beta/network_firewall_policy.yaml b/tpgtools/overrides/compute/beta/network_firewall_policy.yaml index ac4ed8505f0c..ea763ef1b90d 100644 --- a/tpgtools/overrides/compute/beta/network_firewall_policy.yaml +++ b/tpgtools/overrides/compute/beta/network_firewall_policy.yaml @@ -15,3 +15,8 @@ details: id: projects/{{project}}/regions/{{region}}/firewallPolicies/{{name}} location: region +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject + - tpgresource.DefaultProviderRegion diff --git a/tpgtools/overrides/compute/beta/network_firewall_policy_association.yaml b/tpgtools/overrides/compute/beta/network_firewall_policy_association.yaml index 8919dd2c7cf8..3260bc51a574 100644 --- a/tpgtools/overrides/compute/beta/network_firewall_policy_association.yaml +++ b/tpgtools/overrides/compute/beta/network_firewall_policy_association.yaml @@ -31,3 +31,8 @@ - "projects/{{project}}/global/firewallPolicies/{{firewall_policy}}/associations/{{name}}" - "{{project}}/{{firewall_policy}}/{{name}}" location: global +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject + - tpgresource.DefaultProviderRegion diff --git a/tpgtools/overrides/compute/beta/network_firewall_policy_rule.yaml b/tpgtools/overrides/compute/beta/network_firewall_policy_rule.yaml index 6c0153011095..4ad5ccbeee34 100644 --- a/tpgtools/overrides/compute/beta/network_firewall_policy_rule.yaml +++ b/tpgtools/overrides/compute/beta/network_firewall_policy_rule.yaml @@ -17,3 +17,8 @@ details: id: projects/{{project}}/regions/{{region}}/firewallPolicies/{{firewall_policy}}/{{priority}} location: region +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject + - tpgresource.DefaultProviderRegion diff --git a/tpgtools/overrides/compute/firewall_policy.yaml b/tpgtools/overrides/compute/firewall_policy.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/compute/firewall_policy.yaml +++ b/tpgtools/overrides/compute/firewall_policy.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/firewall_policy_association.yaml b/tpgtools/overrides/compute/firewall_policy_association.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/compute/firewall_policy_association.yaml +++ b/tpgtools/overrides/compute/firewall_policy_association.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/firewall_policy_rule.yaml b/tpgtools/overrides/compute/firewall_policy_rule.yaml index e743d253be12..dc91e4f5a9d5 100644 --- a/tpgtools/overrides/compute/firewall_policy_rule.yaml +++ b/tpgtools/overrides/compute/firewall_policy_rule.yaml @@ -2,3 +2,7 @@ field: target_resources details: diffsuppressfunc: tpgresource.CompareSelfLinkOrResourceName +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/compute/network_firewall_policy.yaml b/tpgtools/overrides/compute/network_firewall_policy.yaml index ac4ed8505f0c..ea763ef1b90d 100644 --- a/tpgtools/overrides/compute/network_firewall_policy.yaml +++ b/tpgtools/overrides/compute/network_firewall_policy.yaml @@ -15,3 +15,8 @@ details: id: projects/{{project}}/regions/{{region}}/firewallPolicies/{{name}} location: region +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject + - tpgresource.DefaultProviderRegion diff --git a/tpgtools/overrides/compute/network_firewall_policy_association.yaml b/tpgtools/overrides/compute/network_firewall_policy_association.yaml index 8919dd2c7cf8..3260bc51a574 100644 --- a/tpgtools/overrides/compute/network_firewall_policy_association.yaml +++ b/tpgtools/overrides/compute/network_firewall_policy_association.yaml @@ -31,3 +31,8 @@ - "projects/{{project}}/global/firewallPolicies/{{firewall_policy}}/associations/{{name}}" - "{{project}}/{{firewall_policy}}/{{name}}" location: global +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject + - tpgresource.DefaultProviderRegion diff --git a/tpgtools/overrides/compute/network_firewall_policy_rule.yaml b/tpgtools/overrides/compute/network_firewall_policy_rule.yaml index 6c0153011095..4ad5ccbeee34 100644 --- a/tpgtools/overrides/compute/network_firewall_policy_rule.yaml +++ b/tpgtools/overrides/compute/network_firewall_policy_rule.yaml @@ -17,3 +17,8 @@ details: id: projects/{{project}}/regions/{{region}}/firewallPolicies/{{firewall_policy}}/{{priority}} location: region +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject + - tpgresource.DefaultProviderRegion diff --git a/tpgtools/overrides/containeraws/beta/cluster.yaml b/tpgtools/overrides/containeraws/beta/cluster.yaml index 0c72806bc726..ad5e41a283d3 100644 --- a/tpgtools/overrides/containeraws/beta/cluster.yaml +++ b/tpgtools/overrides/containeraws/beta/cluster.yaml @@ -1,5 +1,9 @@ - type: EXCLUDE field: monitoring_config +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject - type: DIFF_SUPPRESS_FUNC field: control_plane.root_volume.volume_type details: diff --git a/tpgtools/overrides/containeraws/beta/node_pool.yaml b/tpgtools/overrides/containeraws/beta/node_pool.yaml index e16b502f32ef..60a274d2b3d9 100644 --- a/tpgtools/overrides/containeraws/beta/node_pool.yaml +++ b/tpgtools/overrides/containeraws/beta/node_pool.yaml @@ -1,3 +1,7 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject - type: DIFF_SUPPRESS_FUNC field: config.root_volume.volume_type details: diff --git a/tpgtools/overrides/containeraws/cluster.yaml b/tpgtools/overrides/containeraws/cluster.yaml index 793a89736e62..8485cd756c4e 100644 --- a/tpgtools/overrides/containeraws/cluster.yaml +++ b/tpgtools/overrides/containeraws/cluster.yaml @@ -1,3 +1,7 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject - type: DIFF_SUPPRESS_FUNC field: control_plane.root_volume.volume_type details: diff --git a/tpgtools/overrides/containeraws/node_pool.yaml b/tpgtools/overrides/containeraws/node_pool.yaml index 4f76c9df9c1e..a6b6f0589d85 100644 --- a/tpgtools/overrides/containeraws/node_pool.yaml +++ b/tpgtools/overrides/containeraws/node_pool.yaml @@ -1,3 +1,7 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject - type: DIFF_SUPPRESS_FUNC field: config.root_volume.volume_type details: diff --git a/tpgtools/overrides/containerazure/azure_client.yaml b/tpgtools/overrides/containerazure/azure_client.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/containerazure/azure_client.yaml +++ b/tpgtools/overrides/containerazure/azure_client.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/containerazure/beta/azure_client.yaml b/tpgtools/overrides/containerazure/beta/azure_client.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/containerazure/beta/azure_client.yaml +++ b/tpgtools/overrides/containerazure/beta/azure_client.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/containerazure/beta/cluster.yaml b/tpgtools/overrides/containerazure/beta/cluster.yaml index 4ff1c7c72378..9c36ab64d35b 100644 --- a/tpgtools/overrides/containerazure/beta/cluster.yaml +++ b/tpgtools/overrides/containerazure/beta/cluster.yaml @@ -1,6 +1,10 @@ - type: EXCLUDE field: monitoring_config +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject - type: DIFF_SUPPRESS_FUNC field: logging_config.component_config.enable_components details: - diffsuppressfunc: tpgresource.CompareCaseInsensitive \ No newline at end of file + diffsuppressfunc: tpgresource.CompareCaseInsensitive diff --git a/tpgtools/overrides/containerazure/beta/node_pool.yaml b/tpgtools/overrides/containerazure/beta/node_pool.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/containerazure/beta/node_pool.yaml +++ b/tpgtools/overrides/containerazure/beta/node_pool.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/containerazure/cluster.yaml b/tpgtools/overrides/containerazure/cluster.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/containerazure/cluster.yaml +++ b/tpgtools/overrides/containerazure/cluster.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/containerazure/node_pool.yaml b/tpgtools/overrides/containerazure/node_pool.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/containerazure/node_pool.yaml +++ b/tpgtools/overrides/containerazure/node_pool.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataplex/asset.yaml b/tpgtools/overrides/dataplex/asset.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/dataplex/asset.yaml +++ b/tpgtools/overrides/dataplex/asset.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataplex/beta/asset.yaml b/tpgtools/overrides/dataplex/beta/asset.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/dataplex/beta/asset.yaml +++ b/tpgtools/overrides/dataplex/beta/asset.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataplex/beta/lake.yaml b/tpgtools/overrides/dataplex/beta/lake.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/dataplex/beta/lake.yaml +++ b/tpgtools/overrides/dataplex/beta/lake.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataplex/beta/zone.yaml b/tpgtools/overrides/dataplex/beta/zone.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/dataplex/beta/zone.yaml +++ b/tpgtools/overrides/dataplex/beta/zone.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataplex/lake.yaml b/tpgtools/overrides/dataplex/lake.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/dataplex/lake.yaml +++ b/tpgtools/overrides/dataplex/lake.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataplex/zone.yaml b/tpgtools/overrides/dataplex/zone.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/dataplex/zone.yaml +++ b/tpgtools/overrides/dataplex/zone.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataproc/beta/workflow_template.yaml b/tpgtools/overrides/dataproc/beta/workflow_template.yaml index a0cea3403c87..da6b1fa0e6ad 100644 --- a/tpgtools/overrides/dataproc/beta/workflow_template.yaml +++ b/tpgtools/overrides/dataproc/beta/workflow_template.yaml @@ -9,3 +9,7 @@ details: message: >- version is not useful as a configurable field, and will be removed in the future. +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/dataproc/workflow_template.yaml b/tpgtools/overrides/dataproc/workflow_template.yaml index a0cea3403c87..da6b1fa0e6ad 100644 --- a/tpgtools/overrides/dataproc/workflow_template.yaml +++ b/tpgtools/overrides/dataproc/workflow_template.yaml @@ -9,3 +9,7 @@ details: message: >- version is not useful as a configurable field, and will be removed in the future. +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/eventarc/beta/channel.yaml b/tpgtools/overrides/eventarc/beta/channel.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/eventarc/beta/channel.yaml +++ b/tpgtools/overrides/eventarc/beta/channel.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/eventarc/beta/google_channel_config.yaml b/tpgtools/overrides/eventarc/beta/google_channel_config.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/eventarc/beta/google_channel_config.yaml +++ b/tpgtools/overrides/eventarc/beta/google_channel_config.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/eventarc/beta/trigger.yaml b/tpgtools/overrides/eventarc/beta/trigger.yaml index 2b02fd09b9ce..9014b1241575 100644 --- a/tpgtools/overrides/eventarc/beta/trigger.yaml +++ b/tpgtools/overrides/eventarc/beta/trigger.yaml @@ -11,4 +11,7 @@ # 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. - +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/eventarc/channel.yaml b/tpgtools/overrides/eventarc/channel.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/eventarc/channel.yaml +++ b/tpgtools/overrides/eventarc/channel.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/eventarc/google_channel_config.yaml b/tpgtools/overrides/eventarc/google_channel_config.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/eventarc/google_channel_config.yaml +++ b/tpgtools/overrides/eventarc/google_channel_config.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/eventarc/trigger.yaml b/tpgtools/overrides/eventarc/trigger.yaml index 13ed711e62fe..9014b1241575 100644 --- a/tpgtools/overrides/eventarc/trigger.yaml +++ b/tpgtools/overrides/eventarc/trigger.yaml @@ -11,3 +11,7 @@ # 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. +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/firebaserules/beta/release.yaml b/tpgtools/overrides/firebaserules/beta/release.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/firebaserules/beta/release.yaml +++ b/tpgtools/overrides/firebaserules/beta/release.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/firebaserules/beta/ruleset.yaml b/tpgtools/overrides/firebaserules/beta/ruleset.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/firebaserules/beta/ruleset.yaml +++ b/tpgtools/overrides/firebaserules/beta/ruleset.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/firebaserules/release.yaml b/tpgtools/overrides/firebaserules/release.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/firebaserules/release.yaml +++ b/tpgtools/overrides/firebaserules/release.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/firebaserules/ruleset.yaml b/tpgtools/overrides/firebaserules/ruleset.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/firebaserules/ruleset.yaml +++ b/tpgtools/overrides/firebaserules/ruleset.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/gkehub/beta/feature_membership.yaml b/tpgtools/overrides/gkehub/beta/feature_membership.yaml index 2e8b8f32503c..3eac7364e119 100644 --- a/tpgtools/overrides/gkehub/beta/feature_membership.yaml +++ b/tpgtools/overrides/gkehub/beta/feature_membership.yaml @@ -24,4 +24,8 @@ field: mesh.control_plane details: message: >- - Deprecated in favor of the `management` field \ No newline at end of file + Deprecated in favor of the `management` field +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/networkconnectivity/beta/hub.yaml b/tpgtools/overrides/networkconnectivity/beta/hub.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/networkconnectivity/beta/hub.yaml +++ b/tpgtools/overrides/networkconnectivity/beta/hub.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/networkconnectivity/beta/spoke.yaml b/tpgtools/overrides/networkconnectivity/beta/spoke.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/networkconnectivity/beta/spoke.yaml +++ b/tpgtools/overrides/networkconnectivity/beta/spoke.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/networkconnectivity/hub.yaml b/tpgtools/overrides/networkconnectivity/hub.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/networkconnectivity/hub.yaml +++ b/tpgtools/overrides/networkconnectivity/hub.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/networkconnectivity/spoke.yaml b/tpgtools/overrides/networkconnectivity/spoke.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/networkconnectivity/spoke.yaml +++ b/tpgtools/overrides/networkconnectivity/spoke.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/privateca/beta/certificate_template.yaml b/tpgtools/overrides/privateca/beta/certificate_template.yaml index 13ed711e62fe..9014b1241575 100644 --- a/tpgtools/overrides/privateca/beta/certificate_template.yaml +++ b/tpgtools/overrides/privateca/beta/certificate_template.yaml @@ -11,3 +11,7 @@ # 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. +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/privateca/certificate_template.yaml b/tpgtools/overrides/privateca/certificate_template.yaml index 13ed711e62fe..9014b1241575 100644 --- a/tpgtools/overrides/privateca/certificate_template.yaml +++ b/tpgtools/overrides/privateca/certificate_template.yaml @@ -11,3 +11,7 @@ # 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. +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/recaptchaenterprise/beta/key.yaml b/tpgtools/overrides/recaptchaenterprise/beta/key.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/recaptchaenterprise/beta/key.yaml +++ b/tpgtools/overrides/recaptchaenterprise/beta/key.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject diff --git a/tpgtools/overrides/recaptchaenterprise/key.yaml b/tpgtools/overrides/recaptchaenterprise/key.yaml index e69de29bb2d1..af851d79a0c9 100644 --- a/tpgtools/overrides/recaptchaenterprise/key.yaml +++ b/tpgtools/overrides/recaptchaenterprise/key.yaml @@ -0,0 +1,4 @@ +- type: CUSTOMIZE_DIFF + details: + functions: + - tpgresource.DefaultProviderProject From 8fc61a4f616352c95ea5a4a5a20bfba9f7a6b658 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Wed, 6 Sep 2023 09:50:34 -0700 Subject: [PATCH 021/476] Remove cloud iot service (#8868) --- mmv1/products/cloudiot/Device.yaml | 241 ------------------ mmv1/products/cloudiot/DeviceRegistry.yaml | 172 ------------- mmv1/products/cloudiot/product.yaml | 24 -- .../terraform/constants/cloudiot.go.erb | 241 ------------------ .../decoders/cloudiot_device_registry.go.erb | 31 --- .../encoders/cloudiot_device_registry.go.erb | 43 ---- .../examples/cloudiot_device_basic.tf.erb | 8 - .../examples/cloudiot_device_full.tf.erb | 27 -- .../cloudiot_device_registry_basic.tf.erb | 3 - .../cloudiot_device_registry_full.tf.erb | 46 ---- ...y_single_event_notification_configs.tf.erb | 13 - .../cloudiot_device_registry.go.erb | 32 --- .../cloudiot_device_registry.go.erb | 35 --- ...source_cloudiot_device_registry_id_test.go | 33 --- .../resource_cloudiot_device_update_test.go | 104 -------- .../resource_cloudiot_registry_update_test.go | 110 -------- .../cloudiot/test-fixtures/rsa_cert.pem | 17 -- .../cloudiot/test-fixtures/rsa_public.pem | 14 - 18 files changed, 1194 deletions(-) delete mode 100644 mmv1/products/cloudiot/Device.yaml delete mode 100644 mmv1/products/cloudiot/DeviceRegistry.yaml delete mode 100644 mmv1/products/cloudiot/product.yaml delete mode 100644 mmv1/templates/terraform/constants/cloudiot.go.erb delete mode 100644 mmv1/templates/terraform/decoders/cloudiot_device_registry.go.erb delete mode 100644 mmv1/templates/terraform/encoders/cloudiot_device_registry.go.erb delete mode 100644 mmv1/templates/terraform/examples/cloudiot_device_basic.tf.erb delete mode 100644 mmv1/templates/terraform/examples/cloudiot_device_full.tf.erb delete mode 100644 mmv1/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb delete mode 100644 mmv1/templates/terraform/examples/cloudiot_device_registry_full.tf.erb delete mode 100644 mmv1/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb delete mode 100644 mmv1/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb delete mode 100644 mmv1/templates/terraform/pre_update/cloudiot_device_registry.go.erb delete mode 100644 mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_registry_id_test.go delete mode 100644 mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_update_test.go delete mode 100644 mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_registry_update_test.go delete mode 100644 mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_cert.pem delete mode 100644 mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_public.pem diff --git a/mmv1/products/cloudiot/Device.yaml b/mmv1/products/cloudiot/Device.yaml deleted file mode 100644 index 162f73adecec..000000000000 --- a/mmv1/products/cloudiot/Device.yaml +++ /dev/null @@ -1,241 +0,0 @@ -# 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: 'Device' -base_url: '{{registry}}/devices' -self_link: '{{registry}}/devices/{{name}}' -update_verb: :PATCH -update_mask: true -description: | - A Google Cloud IoT Core device. -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/iot/docs/' - api: 'https://cloud.google.com/iot/docs/reference/cloudiot/rest/' -import_format: ['{{%registry}}/devices/{{name}}'] -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'cloudiot_device_basic' - primary_resource_id: 'test-device' - vars: - cloudiot_device_name: 'cloudiot-device' - cloudiot_device_registry_name: 'cloudiot-device-registry' - test_env_vars: - project: :PROJECT_NAME - region: :REGION - - !ruby/object:Provider::Terraform::Examples - name: 'cloudiot_device_full' - primary_resource_id: 'test-device' - vars: - cloudiot_device_name: 'cloudiot-device' - cloudiot_device_registry_name: 'cloudiot-device-registry' - test_env_vars: - project: :PROJECT_NAME - region: :REGION -parameters: - - !ruby/object:Api::Type::String - name: registry - immutable: true - url_param_only: true - required: true - description: | - The name of the device registry where this device should be created. -properties: - - !ruby/object:Api::Type::String - name: 'name' - immutable: true - required: true - description: | - A unique name for the resource. - api_name: 'id' - - !ruby/object:Api::Type::String - name: 'numId' - output: true - description: | - A server-defined unique numeric ID for the device. - This is a more compact way to identify devices, and it is globally unique. - - !ruby/object:Api::Type::Array - name: 'credentials' - description: | - The credentials used to authenticate this device. - max_size: 3 - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::Time - name: 'expirationTime' - description: | - The time at which this credential becomes invalid. - default_from_api: true - - !ruby/object:Api::Type::NestedObject - name: 'publicKey' - required: true - description: | - A public key used to verify the signature of JSON Web Tokens (JWTs). - properties: - - !ruby/object:Api::Type::Enum - name: 'format' - required: true - description: | - The format of the key. - values: - - :RSA_PEM - - :RSA_X509_PEM - - :ES256_PEM - - :ES256_X509_PEM - - !ruby/object:Api::Type::String - name: 'key' - required: true - description: | - The key data. - - !ruby/object:Api::Type::Time - name: 'lastHeartbeatTime' - output: true - description: | - The last time an MQTT PINGREQ was received. - - !ruby/object:Api::Type::Time - name: 'lastEventTime' - output: true - description: | - The last time a telemetry event was received. - - !ruby/object:Api::Type::Time - name: 'lastStateTime' - output: true - description: | - The last time a state event was received. - - !ruby/object:Api::Type::Time - name: 'lastConfigAckTime' - output: true - description: | - The last time a cloud-to-device config version acknowledgment was received from the device. - - !ruby/object:Api::Type::Time - name: 'lastConfigSendTime' - output: true - description: | - The last time a cloud-to-device config version was sent to the device. - - !ruby/object:Api::Type::Boolean - name: 'blocked' - description: | - If a device is blocked, connections or requests from this device will fail. - - !ruby/object:Api::Type::Time - name: 'lastErrorTime' - output: true - description: | - The time the most recent error occurred, such as a failure to publish to Cloud Pub/Sub. - - !ruby/object:Api::Type::NestedObject - name: 'lastErrorStatus' - output: true - description: | - The error message of the most recent error, such as a failure to publish to Cloud Pub/Sub. - properties: - - !ruby/object:Api::Type::Integer - name: 'number' - description: | - The status code, which should be an enum value of google.rpc.Code. - - !ruby/object:Api::Type::String - name: 'message' - description: | - A developer-facing error message, which should be in English. - - !ruby/object:Api::Type::Array - name: 'details' - description: | - A list of messages that carry the error details. - item_type: Api::Type::KeyValuePairs - - !ruby/object:Api::Type::NestedObject - name: 'config' - output: true - description: | - The most recent device configuration, which is eventually sent from Cloud IoT Core to the device. - properties: - - !ruby/object:Api::Type::String - name: 'version' - output: true - description: | - The version of this update. - - !ruby/object:Api::Type::String - name: 'cloudUpdateTime' - output: true - description: | - The time at which this configuration version was updated in Cloud IoT Core. - - !ruby/object:Api::Type::String - name: 'deviceAckTime' - output: true - description: | - The time at which Cloud IoT Core received the acknowledgment from the device, - indicating that the device has received this configuration version. - - !ruby/object:Api::Type::String - name: 'binaryData' - description: | - The device configuration data. - - !ruby/object:Api::Type::NestedObject - name: 'state' - output: true - description: | - The state most recently received from the device. - properties: - - !ruby/object:Api::Type::Time - name: 'updateTime' - description: | - The time at which this state version was updated in Cloud IoT Core. - - !ruby/object:Api::Type::String - name: 'binaryData' - description: | - The device state data. - - !ruby/object:Api::Type::Enum - name: 'logLevel' - allow_empty_object: true - description: | - The logging verbosity for device activity. - values: - - :NONE - - :ERROR - - :INFO - - :DEBUG - - !ruby/object:Api::Type::KeyValuePairs - name: 'metadata' - description: | - The metadata key-value pairs assigned to the device. - - !ruby/object:Api::Type::NestedObject - name: 'gatewayConfig' - description: | - Gateway-related configuration and state. - update_mask_fields: - - 'gateway_config.gateway_auth_method' - properties: - - !ruby/object:Api::Type::Enum - name: 'gatewayType' - default_value: :NON_GATEWAY - immutable: true - description: | - Indicates whether the device is a gateway. - values: - - :GATEWAY - - :NON_GATEWAY - - !ruby/object:Api::Type::Enum - name: 'gatewayAuthMethod' - description: | - Indicates whether the device is a gateway. - values: - - :ASSOCIATION_ONLY - - :DEVICE_AUTH_TOKEN_ONLY - - :ASSOCIATION_AND_DEVICE_AUTH_TOKEN - - !ruby/object:Api::Type::String - name: 'lastAccessedGatewayId' - output: true - description: | - The ID of the gateway the device accessed most recently. - - !ruby/object:Api::Type::Time - name: 'lastAccessedGatewayTime' - output: true - description: | - The most recent time at which the device accessed the gateway specified in last_accessed_gateway. diff --git a/mmv1/products/cloudiot/DeviceRegistry.yaml b/mmv1/products/cloudiot/DeviceRegistry.yaml deleted file mode 100644 index 044a5bf70436..000000000000 --- a/mmv1/products/cloudiot/DeviceRegistry.yaml +++ /dev/null @@ -1,172 +0,0 @@ -# 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: 'DeviceRegistry' -base_url: 'projects/{{project}}/locations/{{region}}/registries' -self_link: 'projects/{{project}}/locations/{{region}}/registries/{{name}}' -update_verb: :PATCH -update_mask: true -description: | - A Google Cloud IoT Core device registry. -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://cloud.google.com/iot/docs/' - api: 'https://cloud.google.com/iot/docs/reference/cloudiot/rest/' -iam_policy: !ruby/object:Api::Resource::IamPolicy - method_name_separator: ':' - fetch_iam_policy_verb: :POST - parent_resource_attribute: 'name' - import_format: - [ - 'projects/{{project}}/locations/{{location}}/registries/{{name}}', - '{{name}}', - ] -legacy_name: 'google_cloudiot_registry' -import_format: ['{{project}}/locations/{{region}}/registries/{{name}}'] -id_format: 'projects/{{project}}/locations/{{region}}/registries/{{name}}' -custom_code: !ruby/object:Provider::Terraform::CustomCode - constants: templates/terraform/constants/cloudiot.go.erb - decoder: templates/terraform/decoders/cloudiot_device_registry.go.erb - encoder: templates/terraform/encoders/cloudiot_device_registry.go.erb - extra_schema_entry: templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb - pre_update: templates/terraform/pre_update/cloudiot_device_registry.go.erb -docs: !ruby/object:Provider::Terraform::Docs - optional_properties: | - * `state_notification_config` - A PubSub topic to publish device state updates. - The structure is documented below. - - * `mqtt_config` - Activate or deactivate MQTT. - The structure is documented below. - - * `http_config` - Activate or deactivate HTTP. - The structure is documented below. - - * `credentials` - List of public key certificates to authenticate devices. - The structure is documented below. - - The `state_notification_config` block supports: - - * `pubsub_topic_name` - PubSub topic name to publish device state updates. - - The `mqtt_config` block supports: - - * `mqtt_enabled_state` - The field allows `MQTT_ENABLED` or `MQTT_DISABLED`. - - The `http_config` block supports: - - * `http_enabled_state` - The field allows `HTTP_ENABLED` or `HTTP_DISABLED`. - - The `credentials` block supports: - - * `public_key_certificate` - A public key certificate format and data. - - The `public_key_certificate` block supports: - - * `format` - The field allows only `X509_CERTIFICATE_PEM`. - - * `certificate` - The certificate data. -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'cloudiot_device_registry_basic' - primary_resource_id: 'test-registry' - primary_resource_name: "fmt.Sprintf(\"tf-test-cloudiot-registry%s\", - context[\"\ - random_suffix\"])" - vars: - cloudiot_registry_name: 'cloudiot-registry' - test_env_vars: - project: :PROJECT_NAME - region: :REGION - - !ruby/object:Provider::Terraform::Examples - name: 'cloudiot_device_registry_single_event_notification_configs' - primary_resource_id: 'test-registry' - vars: - cloudiot_registry_name: 'cloudiot-registry' - cloudiot_device_telemetry_topic_name: 'default-telemetry' - test_env_vars: - project: :PROJECT_NAME - region: :REGION - - !ruby/object:Provider::Terraform::Examples - name: 'cloudiot_device_registry_full' - primary_resource_id: 'test-registry' - vars: - cloudiot_registry_name: 'cloudiot-registry' - cloudiot_device_status_topic_name: 'default-devicestatus' - cloudiot_device_telemetry_topic_name: 'default-telemetry' - cloudiot_additional_device_telemetry_topic_name: 'additional-telemetry' - cloudiot_subfolder_matches_additional_device_telemetry_topic: 'test/path' - test_env_vars: - project: :PROJECT_NAME - region: :REGION -parameters: - - !ruby/object:Api::Type::String - name: region - immutable: true - url_param_only: true - required: false - description: | - The region in which the created registry should reside. - If it is not provided, the provider region is used. - ignore_read: true - default_from_api: true -properties: - - !ruby/object:Api::Type::String - name: 'name' - immutable: true - required: true - description: | - A unique name for the resource, required by device registry. - api_name: 'id' - validation: !ruby/object:Provider::Terraform::Validation - function: 'ValidateCloudIotDeviceRegistryID' - - !ruby/object:Api::Type::Array - name: 'eventNotificationConfigs' - description: | - List of configurations for event notifications, such as PubSub topics - to publish device events to. - max_size: 10 - default_from_api: true - item_type: !ruby/object:Api::Type::NestedObject - properties: - - !ruby/object:Api::Type::String - name: 'subfolderMatches' - description: | - If the subfolder name matches this string exactly, this - configuration will be used. The string must not include the - leading '/' character. If empty, all strings are matched. Empty - value can only be used for the last `event_notification_configs` - item. - validation: !ruby/object:Provider::Terraform::Validation - function: 'validateCloudIotDeviceRegistrySubfolderMatch' - - !ruby/object:Api::Type::String - name: 'pubsubTopicName' - required: true - description: | - PubSub topic name to publish device events. - diff_suppress_func: 'tpgresource.CompareSelfLinkOrResourceName' - - !ruby/object:Api::Type::Enum - name: 'logLevel' - default_value: :NONE - description: | - The default logging verbosity for activity from devices in this - registry. Specifies which events should be written to logs. For - example, if the LogLevel is ERROR, only events that terminate in - errors will be logged. LogLevel is inclusive; enabling INFO logging - will also enable ERROR logging. - values: - - :NONE - - :ERROR - - :INFO - - :DEBUG - diff_suppress_func: 'tpgresource.EmptyOrDefaultStringSuppress("NONE")' diff --git a/mmv1/products/cloudiot/product.yaml b/mmv1/products/cloudiot/product.yaml deleted file mode 100644 index 2539129f14da..000000000000 --- a/mmv1/products/cloudiot/product.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2020 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::Product -name: CloudIot -display_name: Cloud IoT Core -legacy_name: 'cloudiot' -versions: - - !ruby/object:Api::Product::Version - name: ga - base_url: https://cloudiot.googleapis.com/v1/ -scopes: - - https://www.googleapis.com/auth/cloudiot - - https://www.googleapis.com/auth/cloud-platform diff --git a/mmv1/templates/terraform/constants/cloudiot.go.erb b/mmv1/templates/terraform/constants/cloudiot.go.erb deleted file mode 100644 index 03905061d6ef..000000000000 --- a/mmv1/templates/terraform/constants/cloudiot.go.erb +++ /dev/null @@ -1,241 +0,0 @@ -func expandCloudIotDeviceRegistryHTTPConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedHTTPEnabledState, err := expandCloudIotDeviceRegistryHTTPEnabledState(original["http_enabled_state"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedHTTPEnabledState); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["httpEnabledState"] = transformedHTTPEnabledState - } - - return transformed, nil -} - -func expandCloudIotDeviceRegistryHTTPEnabledState(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandCloudIotDeviceRegistryMqttConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedMqttEnabledState, err := expandCloudIotDeviceRegistryMqttEnabledState(original["mqtt_enabled_state"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedMqttEnabledState); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["mqttEnabledState"] = transformedMqttEnabledState - } - - return transformed, nil -} - -func expandCloudIotDeviceRegistryMqttEnabledState(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandCloudIotDeviceRegistryStateNotificationConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedPubsubTopicName, err := expandCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(original["pubsub_topic_name"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedPubsubTopicName); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["pubsubTopicName"] = transformedPubsubTopicName - } - - return transformed, nil -} - -func expandCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandCloudIotDeviceRegistryCredentials(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - req := make([]interface{}, 0, len(l)) - - for _, raw := range l { - if raw == nil { - continue - } - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedPublicKeyCertificate, err := expandCloudIotDeviceRegistryCredentialsPublicKeyCertificate(original["public_key_certificate"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedPublicKeyCertificate); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["publicKeyCertificate"] = transformedPublicKeyCertificate - } - - req = append(req, transformed) - } - - return req, nil -} - -func expandCloudIotDeviceRegistryCredentialsPublicKeyCertificate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedFormat, err := expandCloudIotDeviceRegistryPublicKeyCertificateFormat(original["format"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedFormat); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["format"] = transformedFormat - } - - transformedCertificate, err := expandCloudIotDeviceRegistryPublicKeyCertificateCertificate(original["certificate"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedCertificate); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["certificate"] = transformedCertificate - } - - return transformed, nil -} - -func expandCloudIotDeviceRegistryPublicKeyCertificateFormat(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandCloudIotDeviceRegistryPublicKeyCertificateCertificate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func flattenCloudIotDeviceRegistryCredentials(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - log.Printf("[DEBUG] Flattening device resitry credentials: %q", d.Id()) - if v == nil { - log.Printf("[DEBUG] The credentials array is nil: %q", d.Id()) - return v - } - l := v.([]interface{}) - transformed := make([]interface{}, 0, len(l)) - for _, raw := range l { - original := raw.(map[string]interface{}) - log.Printf("[DEBUG] Original credential: %+v", original) - if len(original) < 1 { - log.Printf("[DEBUG] Excluding empty credential that the API returned. %q", d.Id()) - continue - } - log.Printf("[DEBUG] Credentials array before appending a new credential: %+v", transformed) - transformed = append(transformed, map[string]interface{}{ - "public_key_certificate": flattenCloudIotDeviceRegistryCredentialsPublicKeyCertificate(original["publicKeyCertificate"], d, config), - }) - log.Printf("[DEBUG] Credentials array after appending a new credential: %+v", transformed) - } - return transformed -} - -func flattenCloudIotDeviceRegistryCredentialsPublicKeyCertificate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - log.Printf("[DEBUG] Flattening device resitry credentials public key certificate: %q", d.Id()) - if v == nil { - log.Printf("[DEBUG] The public key certificate is nil: %q", d.Id()) - return v - } - - original := v.(map[string]interface{}) - log.Printf("[DEBUG] Original public key certificate: %+v", original) - transformed := make(map[string]interface{}) - - transformedPublicKeyCertificateFormat := flattenCloudIotDeviceRegistryPublicKeyCertificateFormat(original["format"], d, config) - transformed["format"] = transformedPublicKeyCertificateFormat - - transformedPublicKeyCertificateCertificate := flattenCloudIotDeviceRegistryPublicKeyCertificateCertificate(original["certificate"], d, config) - transformed["certificate"] = transformedPublicKeyCertificateCertificate - - log.Printf("[DEBUG] Transformed public key certificate: %+v", transformed) - - return transformed -} - -func flattenCloudIotDeviceRegistryPublicKeyCertificateFormat(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenCloudIotDeviceRegistryPublicKeyCertificateCertificate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenCloudIotDeviceRegistryHTTPConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return v - } - - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedHTTPEnabledState := flattenCloudIotDeviceRegistryHTTPConfigHTTPEnabledState(original["httpEnabledState"], d, config) - transformed["http_enabled_state"] = transformedHTTPEnabledState - - return transformed -} - -func flattenCloudIotDeviceRegistryHTTPConfigHTTPEnabledState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenCloudIotDeviceRegistryMqttConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return v - } - - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedMqttEnabledState := flattenCloudIotDeviceRegistryMqttConfigMqttEnabledState(original["mqttEnabledState"], d, config) - transformed["mqtt_enabled_state"] = transformedMqttEnabledState - - return transformed -} - -func flattenCloudIotDeviceRegistryMqttConfigMqttEnabledState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenCloudIotDeviceRegistryStateNotificationConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - log.Printf("[DEBUG] Flattening state notification config: %+v", v) - if v == nil { - return v - } - - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedPubsubTopicName := flattenCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(original["pubsubTopicName"], d, config) - if val := reflect.ValueOf(transformedPubsubTopicName); val.IsValid() && !tpgresource.IsEmptyValue(val) { - log.Printf("[DEBUG] pubsub topic name is not null: %v", d.Get("pubsub_topic_name")) - transformed["pubsub_topic_name"] = transformedPubsubTopicName - } - - - return transformed -} - -func flattenCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func ValidateCloudIotDeviceRegistryID(v interface{}, k string) (warnings []string, errors []error) { - value := v.(string) - if strings.HasPrefix(value, "goog") { - errors = append(errors, fmt.Errorf( - "%q (%q) can not start with \"goog\"", k, value)) - } - if !regexp.MustCompile(verify.CloudIoTIdRegex).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q (%q) doesn't match regexp %q", k, value, verify.CloudIoTIdRegex)) - } - return -} - -func validateCloudIotDeviceRegistrySubfolderMatch(v interface{}, k string) (warnings []string, errors []error) { - value := v.(string) - if strings.HasPrefix(value, "/") { - errors = append(errors, fmt.Errorf( - "%q (%q) can not start with '/'", k, value)) - } - return -} diff --git a/mmv1/templates/terraform/decoders/cloudiot_device_registry.go.erb b/mmv1/templates/terraform/decoders/cloudiot_device_registry.go.erb deleted file mode 100644 index b5652175ebee..000000000000 --- a/mmv1/templates/terraform/decoders/cloudiot_device_registry.go.erb +++ /dev/null @@ -1,31 +0,0 @@ -config := meta.(*transport_tpg.Config) - -log.Printf("[DEBUG] Decoding state notification config: %q", d.Id()) -log.Printf("[DEBUG] State notification config before decoding: %v", d.Get("state_notification_config")) -if err := d.Set("state_notification_config", flattenCloudIotDeviceRegistryStateNotificationConfig(res["stateNotificationConfig"], d, config)); err != nil { - return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err) -} -log.Printf("[DEBUG] State notification config after decoding: %v", d.Get("state_notification_config")) - -log.Printf("[DEBUG] Decoding HTTP config: %q", d.Id()) -log.Printf("[DEBUG] HTTP config before decoding: %v", d.Get("http_config")) -if err := d.Set("http_config", flattenCloudIotDeviceRegistryHTTPConfig(res["httpConfig"], d, config)); err != nil { - return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err) -} -log.Printf("[DEBUG] HTTP config after decoding: %v", d.Get("http_config")) - -log.Printf("[DEBUG] Decoding MQTT config: %q", d.Id()) -log.Printf("[DEBUG] MQTT config before decoding: %v", d.Get("mqtt_config")) -if err := d.Set("mqtt_config", flattenCloudIotDeviceRegistryMqttConfig(res["mqttConfig"], d, config)); err != nil { - return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err) -} -log.Printf("[DEBUG] MQTT config after decoding: %v", d.Get("mqtt_config")) - -log.Printf("[DEBUG] Decoding credentials: %q", d.Id()) -log.Printf("[DEBUG] credentials before decoding: %v", d.Get("credentials")) -if err := d.Set("credentials", flattenCloudIotDeviceRegistryCredentials(res["credentials"], d, config)); err != nil { - return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err) -} -log.Printf("[DEBUG] credentials after decoding: %v", d.Get("credentials")) - -return res, nil diff --git a/mmv1/templates/terraform/encoders/cloudiot_device_registry.go.erb b/mmv1/templates/terraform/encoders/cloudiot_device_registry.go.erb deleted file mode 100644 index 37794ff71630..000000000000 --- a/mmv1/templates/terraform/encoders/cloudiot_device_registry.go.erb +++ /dev/null @@ -1,43 +0,0 @@ -config := meta.(*transport_tpg.Config) - -log.Printf("[DEBUG] Resource data before encoding extra schema entries %q: %#v", d.Id(), obj) - -log.Printf("[DEBUG] Encoding state notification config: %q", d.Id()) -stateNotificationConfigProp, err := expandCloudIotDeviceRegistryStateNotificationConfig(d.Get("state_notification_config"), d, config) -if err != nil { - return nil, err -} else if v, ok := d.GetOkExists("state_notification_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(stateNotificationConfigProp)) && (ok || !reflect.DeepEqual(v, stateNotificationConfigProp)) { - log.Printf("[DEBUG] Encoding %q. Setting stateNotificationConfig: %#v", d.Id(), stateNotificationConfigProp) - obj["stateNotificationConfig"] = stateNotificationConfigProp -} - -log.Printf("[DEBUG] Encoding HTTP config: %q", d.Id()) -httpConfigProp, err := expandCloudIotDeviceRegistryHTTPConfig(d.Get("http_config"), d, config) -if err != nil { - return nil, err -} else if v, ok := d.GetOkExists("http_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(httpConfigProp)) && (ok || !reflect.DeepEqual(v, httpConfigProp)) { - log.Printf("[DEBUG] Encoding %q. Setting httpConfig: %#v", d.Id(), httpConfigProp) - obj["httpConfig"] = httpConfigProp -} - -log.Printf("[DEBUG] Encoding MQTT config: %q", d.Id()) -mqttConfigProp, err := expandCloudIotDeviceRegistryMqttConfig(d.Get("mqtt_config"), d, config) -if err != nil { - return nil, err -} else if v, ok := d.GetOkExists("mqtt_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(mqttConfigProp)) && (ok || !reflect.DeepEqual(v, mqttConfigProp)) { - log.Printf("[DEBUG] Encoding %q. Setting mqttConfig: %#v", d.Id(), mqttConfigProp) - obj["mqttConfig"] = mqttConfigProp -} - -log.Printf("[DEBUG] Encoding credentials: %q", d.Id()) -credentialsProp, err := expandCloudIotDeviceRegistryCredentials(d.Get("credentials"), d, config) -if err != nil { - return nil, err -} else if v, ok := d.GetOkExists("credentials"); !tpgresource.IsEmptyValue(reflect.ValueOf(credentialsProp)) && (ok || !reflect.DeepEqual(v, credentialsProp)) { - log.Printf("[DEBUG] Encoding %q. Setting credentials: %#v", d.Id(), credentialsProp) - obj["credentials"] = credentialsProp -} - -log.Printf("[DEBUG] Resource data after encoding extra schema entries %q: %#v", d.Id(), obj) - -return obj, nil diff --git a/mmv1/templates/terraform/examples/cloudiot_device_basic.tf.erb b/mmv1/templates/terraform/examples/cloudiot_device_basic.tf.erb deleted file mode 100644 index dbfd02b17e4d..000000000000 --- a/mmv1/templates/terraform/examples/cloudiot_device_basic.tf.erb +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_cloudiot_registry" "registry" { - name = "<%= ctx[:vars]['cloudiot_device_registry_name'] %>" -} - -resource "google_cloudiot_device" "<%= ctx[:primary_resource_id] %>" { - name = "<%= ctx[:vars]['cloudiot_device_name'] %>" - registry = google_cloudiot_registry.registry.id -} diff --git a/mmv1/templates/terraform/examples/cloudiot_device_full.tf.erb b/mmv1/templates/terraform/examples/cloudiot_device_full.tf.erb deleted file mode 100644 index 0c3457d4029c..000000000000 --- a/mmv1/templates/terraform/examples/cloudiot_device_full.tf.erb +++ /dev/null @@ -1,27 +0,0 @@ -resource "google_cloudiot_registry" "registry" { - name = "<%= ctx[:vars]['cloudiot_device_registry_name'] %>" -} - -resource "google_cloudiot_device" "<%= ctx[:primary_resource_id] %>" { - name = "<%= ctx[:vars]['cloudiot_device_name'] %>" - registry = google_cloudiot_registry.registry.id - - credentials { - public_key { - format = "RSA_PEM" - key = file("test-fixtures/rsa_public.pem") - } - } - - blocked = false - - log_level = "INFO" - - metadata = { - test_key_1 = "test_value_1" - } - - gateway_config { - gateway_type = "NON_GATEWAY" - } -} diff --git a/mmv1/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb b/mmv1/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb deleted file mode 100644 index 67bf5e108304..000000000000 --- a/mmv1/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb +++ /dev/null @@ -1,3 +0,0 @@ -resource "google_cloudiot_registry" "<%= ctx[:primary_resource_id] %>" { - name = "<%= ctx[:vars]['cloudiot_registry_name'] %>" -} diff --git a/mmv1/templates/terraform/examples/cloudiot_device_registry_full.tf.erb b/mmv1/templates/terraform/examples/cloudiot_device_registry_full.tf.erb deleted file mode 100644 index f5c11d9abdcc..000000000000 --- a/mmv1/templates/terraform/examples/cloudiot_device_registry_full.tf.erb +++ /dev/null @@ -1,46 +0,0 @@ -resource "google_pubsub_topic" "default-devicestatus" { - name = "<%= ctx[:vars]['cloudiot_device_status_topic_name'] %>" -} - -resource "google_pubsub_topic" "default-telemetry" { - name = "<%= ctx[:vars]['cloudiot_device_telemetry_topic_name'] %>" -} - -resource "google_pubsub_topic" "additional-telemetry" { - name = "<%= ctx[:vars]['cloudiot_additional_device_telemetry_topic_name'] %>" -} - -resource "google_cloudiot_registry" "<%= ctx[:primary_resource_id] %>" { - name = "<%= ctx[:vars]['cloudiot_registry_name'] %>" - - event_notification_configs { - pubsub_topic_name = google_pubsub_topic.additional-telemetry.id - subfolder_matches = "<%= ctx[:vars]['cloudiot_subfolder_matches_additional_device_telemetry_topic'] %>" - } - - event_notification_configs { - pubsub_topic_name = google_pubsub_topic.default-telemetry.id - subfolder_matches = "" - } - - state_notification_config = { - pubsub_topic_name = google_pubsub_topic.default-devicestatus.id - } - - mqtt_config = { - mqtt_enabled_state = "MQTT_ENABLED" - } - - http_config = { - http_enabled_state = "HTTP_ENABLED" - } - - log_level = "INFO" - - credentials { - public_key_certificate = { - format = "X509_CERTIFICATE_PEM" - certificate = file("test-fixtures/rsa_cert.pem") - } - } -} diff --git a/mmv1/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb b/mmv1/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb deleted file mode 100644 index 45139229a27c..000000000000 --- a/mmv1/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb +++ /dev/null @@ -1,13 +0,0 @@ -resource "google_pubsub_topic" "default-telemetry" { - name = "<%= ctx[:vars]['cloudiot_device_telemetry_topic_name'] %>" -} - -resource "google_cloudiot_registry" "<%= ctx[:primary_resource_id] %>" { - name = "<%= ctx[:vars]['cloudiot_registry_name'] %>" - - event_notification_configs { - pubsub_topic_name = google_pubsub_topic.default-telemetry.id - subfolder_matches = "" - } - -} diff --git a/mmv1/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb b/mmv1/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb deleted file mode 100644 index 7a1a8eec8f7a..000000000000 --- a/mmv1/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb +++ /dev/null @@ -1,32 +0,0 @@ -"state_notification_config": { - Type: schema.TypeMap, - Description: `A PubSub topic to publish device state updates.`, - Optional: true, -}, -"mqtt_config": { - Type: schema.TypeMap, - Description: `Activate or deactivate MQTT.`, - Computed: true, - Optional: true, -}, -"http_config": { - Type: schema.TypeMap, - Description: `Activate or deactivate HTTP.`, - Computed: true, - Optional: true, -}, -"credentials": { - Type: schema.TypeList, - Description: `List of public key certificates to authenticate devices.`, - Optional: true, - MaxItems: 10, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "public_key_certificate": { - Type: schema.TypeMap, - Description: `A public key certificate format and data.`, - Required: true, - }, - }, - }, -}, diff --git a/mmv1/templates/terraform/pre_update/cloudiot_device_registry.go.erb b/mmv1/templates/terraform/pre_update/cloudiot_device_registry.go.erb deleted file mode 100644 index 226c0efca146..000000000000 --- a/mmv1/templates/terraform/pre_update/cloudiot_device_registry.go.erb +++ /dev/null @@ -1,35 +0,0 @@ -log.Printf("[DEBUG] updateMask before adding extra schema entries %q: %v", d.Id(), updateMask) - -log.Printf("[DEBUG] Pre-update on state notification config: %q", d.Id()) -if d.HasChange("state_notification_config") { - log.Printf("[DEBUG] %q stateNotificationConfig.pubsubTopicName has a change. Adding it to the update mask", d.Id()) - updateMask = append(updateMask, "stateNotificationConfig.pubsubTopicName") -} - -log.Printf("[DEBUG] Pre-update on MQTT config: %q", d.Id()) -if d.HasChange("mqtt_config") { - log.Printf("[DEBUG] %q mqttConfig.mqttEnabledState has a change. Adding it to the update mask", d.Id()) - updateMask = append(updateMask, "mqttConfig.mqttEnabledState") -} - -log.Printf("[DEBUG] Pre-update on HTTP config: %q", d.Id()) -if d.HasChange("http_config") { - log.Printf("[DEBUG] %q httpConfig.httpEnabledState has a change. Adding it to the update mask", d.Id()) - updateMask = append(updateMask, "httpConfig.httpEnabledState") -} - -log.Printf("[DEBUG] Pre-update on credentials: %q", d.Id()) -if d.HasChange("credentials") { - log.Printf("[DEBUG] %q credentials has a change. Adding it to the update mask", d.Id()) - updateMask = append(updateMask, "credentials") -} - -log.Printf("[DEBUG] updateMask after adding extra schema entries %q: %v", d.Id(), updateMask) - -// Refreshing updateMask after adding extra schema entries -url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) -if err != nil { - return err -} - -log.Printf("[DEBUG] Update URL %q: %v", d.Id(), url) diff --git a/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_registry_id_test.go b/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_registry_id_test.go deleted file mode 100644 index 41d926e421e0..000000000000 --- a/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_registry_id_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package cloudiot_test - -import ( - "strings" - "testing" - - "github.com/hashicorp/terraform-provider-google/google/services/cloudiot" - "github.com/hashicorp/terraform-provider-google/google/verify" -) - -func TestValidateCloudIoTDeviceRegistryId(t *testing.T) { - x := []verify.StringValidationTestCase{ - // No errors - {TestName: "basic", Value: "foobar"}, - {TestName: "with numbers", Value: "foobar123"}, - {TestName: "short", Value: "foo"}, - {TestName: "long", Value: "foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo"}, - {TestName: "has a hyphen", Value: "foo-bar"}, - - // With errors - {TestName: "empty", Value: "", ExpectError: true}, - {TestName: "starts with a goog", Value: "googfoobar", ExpectError: true}, - {TestName: "starts with a number", Value: "1foobar", ExpectError: true}, - {TestName: "has an slash", Value: "foo/bar", ExpectError: true}, - {TestName: "has an backslash", Value: "foo\bar", ExpectError: true}, - {TestName: "too long", Value: strings.Repeat("f", 260), ExpectError: true}, - } - - es := verify.TestStringValidationCases(x, cloudiot.ValidateCloudIotDeviceRegistryID) - if len(es) > 0 { - t.Errorf("Failed to validate CloudIoT ID names: %v", es) - } -} diff --git a/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_update_test.go b/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_update_test.go deleted file mode 100644 index 799b4a58c372..000000000000 --- a/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_device_update_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package cloudiot_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-provider-google/google/acctest" -) - -func TestAccCloudIoTDevice_update(t *testing.T) { - t.Parallel() - - registryName := fmt.Sprintf("psregistry-test-%s", acctest.RandString(t, 10)) - deviceName := fmt.Sprintf("psdevice-test-%s", acctest.RandString(t, 10)) - resourceName := fmt.Sprintf("google_cloudiot_device.%s", deviceName) - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckCloudIotDeviceDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccCloudIoTDeviceBasic(deviceName, registryName), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccCloudIoTDeviceExtended(deviceName, registryName), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccCloudIoTDeviceBasic(deviceName, registryName), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccCloudIoTDeviceBasic(deviceName string, registryName string) string { - return fmt.Sprintf(` - -resource "google_cloudiot_registry" "%s" { - name = "%s" -} - -resource "google_cloudiot_device" "%s" { - name = "%s" - registry = google_cloudiot_registry.%s.id - - gateway_config { - gateway_auth_method = "DEVICE_AUTH_TOKEN_ONLY" - gateway_type = "GATEWAY" - } -} - - -`, registryName, registryName, deviceName, deviceName, registryName) -} - -func testAccCloudIoTDeviceExtended(deviceName string, registryName string) string { - return fmt.Sprintf(` - -resource "google_cloudiot_registry" "%s" { - name = "%s" -} - -resource "google_cloudiot_device" "%s" { - name = "%s" - registry = google_cloudiot_registry.%s.id - - credentials { - public_key { - format = "RSA_PEM" - key = file("test-fixtures/rsa_public.pem") - } - } - - blocked = false - - log_level = "INFO" - - metadata = { - test_key_1 = "test_value_1" - } - - gateway_config { - gateway_auth_method = "ASSOCIATION_AND_DEVICE_AUTH_TOKEN" - gateway_type = "GATEWAY" - } -} -`, registryName, registryName, deviceName, deviceName, registryName) -} diff --git a/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_registry_update_test.go b/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_registry_update_test.go deleted file mode 100644 index 9493f26bd4ca..000000000000 --- a/mmv1/third_party/terraform/services/cloudiot/resource_cloudiot_registry_update_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package cloudiot_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-provider-google/google/acctest" -) - -func TestAccCloudIoTRegistry_update(t *testing.T) { - t.Parallel() - - registryName := fmt.Sprintf("psregistry-test-%s", acctest.RandString(t, 10)) - resourceName := fmt.Sprintf("google_cloudiot_registry.%s", registryName) - deviceStatus := fmt.Sprintf("psregistry-test-devicestatus-%s", acctest.RandString(t, 10)) - defaultTelemetry := fmt.Sprintf("psregistry-test-telemetry-%s", acctest.RandString(t, 10)) - additionalTelemetry := fmt.Sprintf("psregistry-additional-test-telemetry-%s", acctest.RandString(t, 10)) - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckCloudIotDeviceRegistryDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccCloudIoTRegistryBasic(registryName), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccCloudIoTRegistryExtended(registryName, deviceStatus, defaultTelemetry, additionalTelemetry), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccCloudIoTRegistryBasic(registryName), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccCloudIoTRegistryBasic(registryName string) string { - return fmt.Sprintf(` - -resource "google_cloudiot_registry" "%s" { - name = "%s" -} -`, registryName, registryName) -} - -func testAccCloudIoTRegistryExtended(registryName string, deviceStatus string, defaultTelemetry string, additionalTelemetry string) string { - return fmt.Sprintf(` - -resource "google_pubsub_topic" "default-devicestatus" { - name = "psregistry-test-devicestatus-%s" -} - -resource "google_pubsub_topic" "default-telemetry" { - name = "psregistry-test-telemetry-%s" -} - -resource "google_pubsub_topic" "additional-telemetry" { - name = "psregistry-additional-test-telemetry-%s" -} - -resource "google_cloudiot_registry" "%s" { - name = "%s" - - event_notification_configs { - pubsub_topic_name = google_pubsub_topic.additional-telemetry.id - subfolder_matches = "test/directory" - } - - event_notification_configs { - pubsub_topic_name = google_pubsub_topic.default-telemetry.id - subfolder_matches = "" - } - - state_notification_config = { - pubsub_topic_name = google_pubsub_topic.default-devicestatus.id - } - - mqtt_config = { - mqtt_enabled_state = "MQTT_DISABLED" - } - - http_config = { - http_enabled_state = "HTTP_DISABLED" - } - - credentials { - public_key_certificate = { - format = "X509_CERTIFICATE_PEM" - certificate = file("test-fixtures/rsa_cert.pem") - } - } -} -`, deviceStatus, defaultTelemetry, additionalTelemetry, registryName, registryName) -} diff --git a/mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_cert.pem b/mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_cert.pem deleted file mode 100644 index d8a834633c91..000000000000 --- a/mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICoDCCAYgCCQDzZ6R7RYs0sTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZ1 -bnVzZWQwIBcNMTgwMTIwMTA0OTIzWhgPNDc1NTEyMTgxMDQ5MjNaMBExDzANBgNV -BAMMBnVudXNlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMXX/5jI -tvxpst1mFVKVXfyu5S5AOQF+i/ny6Ef+h8py8y42XfsE2AAPSTE3JCIgWemw7NQ/ -xnTQ3f6b7/6+ZsdM4/hoiedwYV8X3LVPB9NRnKe82OHUhzo1psVMJVvHtE3GsD/V -i40ki/L4Xs64E2GJqQfrkgeNfIyCeKev64fR5aMazqOw1cNrVe34mY3L1hgXpn7e -SnO0oqnV86pTh+jTT8EKgo9AI7/QuJbPWpJhnj1/Fm8i3DdCdpQqloX9Fc4f6whA -XlZ2tkma0PsBraxMua5GPglJ7m3RabQIoyAW+4hEYAcu7U0wIhCK+C8WTNgEYZaK -zvp8vK6vOgBIjE0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAvVXus7dLikEAM6+I -6xeN7aHEMJRR0h2rigLiYjfl8R9zG/zxUPUunWPAYaKvWOFviXcX/KqpjDqIIeWx -Gm0yNfyalHq476nRCf/0t9AH5X4Qy0KJSW5KfhQLG9X2z/UiJxwHKCwaWZtEEzPu -mGqvwhNXUOL/GuAZCJWPdWrUGM4kHHz3kw5v3UPNS2xA7yMtN9N1b8/pkTQ77XNk -DA4wngA5zc7Ae72SJDrY8XXqLfL4Nagkrn6AOhGK3/Ewvca6hkThMcHI0WF2AqFo -mo3iGUJzR5lOUx+4RiEBC5NNEZsE9GMNEiu8kYvCAS0FMKYmxFPGx1U/kiOeeuIw -W3sOEA== ------END CERTIFICATE----- diff --git a/mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_public.pem b/mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_public.pem deleted file mode 100644 index 2b2acadf6760..000000000000 --- a/mmv1/third_party/terraform/services/cloudiot/test-fixtures/rsa_public.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv6weC1aT16l2qS6qdYcy -7BOjzP7TwT9zUAiFhWpL256GRqC8yQRdqMsi68Q//762IUyu/qaHbEgQ8WRmQdVV -GDlxkBfrA/iXB2dgujq8jh0HWIV2ev3TerV3aUwvYUlrowhq027SX9U1hbufdGCM -uKsHiF05ErgNvEuR8XAkeJ/YV2DV2+sRq+Wg9y4RwUYbdchdFty1d5SX/s0Yqswg -yOG9VoCdR7baF22ughVR44aRm+83mgtqAZ4M+Rpe7JGRsUGY/pR391Toi0s8En15 -JGiAhqX2W0Uo/FZZry3yuqRfdHYENB+ADuyTMTrUaKZv7eua0lTBz5oom3jSF3gv -I7SQoLdK/jhEVOOq41IjB8D60Sgd69bD7yTI516yvZ/s3AyKzW6f6KnjdbCcZKKT -0GAePNLNhDYfSlA9bwJ8HQS2FenSpSTArKvGiVrsinJuNjbQdPuQHcpWf9x1m3GR -TMvF+TNYM/lp7IL2VMbJRfWPy1iWxm9F1Yr6dkHVoLP7ocYkNRHoPLut5E6IFJtK -lVI2NneUYJGnYSO+1xPV9TqlJeMNwr3uFMAN8N/oB3f4WWwuRYgR0L5g2A+Lvx+g -bbdl+Tb/0CNfslfSuDrFV8Z4n6gVwb9ZPGlNHCvnqRfLUpRFJwmR7UYvzi/E7rXJ -EDkK+tcnPkz2JtjdLKR7qVcCAwEAAQ== ------END PUBLIC KEY----- From bf3f834dca11414c0e7d64344cde5c6552f25df4 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Wed, 6 Sep 2023 11:41:32 -0700 Subject: [PATCH 022/476] Add provider default labels (#8670) * Add provider default labels * Fix the filed names * Fix the field name * Don't expand lables field * Fix syntax errors * Fix bug to set metadata.0.terraform_labels * Ignore state verify for terraform_labels * Add logs * Add more logs * Skip test if vcr is enabled * Add new type KeyValueTerraformLabels * Fix rake test * Add terraform_labels to tfplan.json files * Comment out tgc integration tests --- .ci/gcb-generate-diffs-new.yml | 76 +++---- mmv1/api/resource.rb | 40 +++- mmv1/api/type.rb | 10 +- mmv1/compiler.rb | 4 +- mmv1/products/compute/ForwardingRule.yaml | 2 +- mmv1/products/compute/GlobalAddress.yaml | 2 +- .../compute/GlobalForwardingRule.yaml | 2 +- mmv1/products/compute/VpnTunnel.yaml | 2 +- mmv1/provider/core.rb | 3 +- mmv1/provider/terraform.rb | 1 + .../examples/base_configs/test_file.go.erb | 2 +- .../terraform/flatten_property_method.erb | 2 +- .../terraform/post_create/labels.erb | 14 +- .../terraform/fwmodels/provider_model.go.erb | 1 + .../fwprovider/framework_provider.go.erb | 4 + .../terraform/provider/provider.go.erb | 13 ++ .../resource_bigquery_dataset_test.go | 20 +- .../resource_compute_address_test.go.erb | 185 +++++++++++++++++- ...source_compute_forwarding_rule_test.go.erb | 2 + ...compute_global_forwarding_rule_test.go.erb | 4 +- .../terraform/tpgresource/labels.go | 61 ++++++ .../terraform/transport/config.go.erb | 1 + .../data/example_bigquery_dataset.tfplan.json | 7 + ...e_bigquery_dataset_iam_binding.tfplan.json | 7 + ...le_bigquery_dataset_iam_member.tfplan.json | 7 + ...le_bigquery_dataset_iam_policy.tfplan.json | 7 + 26 files changed, 406 insertions(+), 73 deletions(-) create mode 100644 mmv1/third_party/terraform/tpgresource/labels.go diff --git a/.ci/gcb-generate-diffs-new.yml b/.ci/gcb-generate-diffs-new.yml index 8a8a93377a88..d998cd945140 100644 --- a/.ci/gcb-generate-diffs-new.yml +++ b/.ci/gcb-generate-diffs-new.yml @@ -200,45 +200,45 @@ steps: - "17" # Build step - terraform-google-conversion - - name: 'gcr.io/graphite-docker-images/go-plus' - id: tgc-test-integration-0.12.31 - entrypoint: '/workspace/.ci/scripts/go-plus/terraform-validator-tester-integration/test_terraform_validator_integration.sh' - allowFailure: true - secretEnv: ["GITHUB_TOKEN"] - waitFor: ["tpgb-head", "tpgb-base", "tgc-head", "tgc-base"] - env: - - TERRAFORM_VERSION=0.12.31 - - TEST_PROJECT=$_VALIDATOR_TEST_PROJECT - - TEST_FOLDER_ID=$_VALIDATOR_TEST_FOLDER - - TEST_ANCESTRY=$_VALIDATOR_TEST_ANCESTRY - - TEST_ORG_ID=$_VALIDATOR_TEST_ORG - args: - - $_PR_NUMBER - - $COMMIT_SHA - - $BUILD_ID - - $PROJECT_ID - - "18" # Build step - - terraform-google-conversion + # - name: 'gcr.io/graphite-docker-images/go-plus' + # id: tgc-test-integration-0.12.31 + # entrypoint: '/workspace/.ci/scripts/go-plus/terraform-validator-tester-integration/test_terraform_validator_integration.sh' + # allowFailure: true + # secretEnv: ["GITHUB_TOKEN"] + # waitFor: ["tpgb-head", "tpgb-base", "tgc-head", "tgc-base"] + # env: + # - TERRAFORM_VERSION=0.12.31 + # - TEST_PROJECT=$_VALIDATOR_TEST_PROJECT + # - TEST_FOLDER_ID=$_VALIDATOR_TEST_FOLDER + # - TEST_ANCESTRY=$_VALIDATOR_TEST_ANCESTRY + # - TEST_ORG_ID=$_VALIDATOR_TEST_ORG + # args: + # - $_PR_NUMBER + # - $COMMIT_SHA + # - $BUILD_ID + # - $PROJECT_ID + # - "18" # Build step + # - terraform-google-conversion - - name: 'gcr.io/graphite-docker-images/go-plus' - id: tgc-test-integration-0.13.7 - entrypoint: '/workspace/.ci/scripts/go-plus/terraform-validator-tester-integration/test_terraform_validator_integration.sh' - allowFailure: true - secretEnv: ["GITHUB_TOKEN"] - waitFor: ["tpgb-head", "tpgb-base", "tgc-head", "tgc-base"] - env: - - TERRAFORM_VERSION=0.13.7 - - TEST_PROJECT=$_VALIDATOR_TEST_PROJECT - - TEST_FOLDER_ID=$_VALIDATOR_TEST_FOLDER - - TEST_ANCESTRY=$_VALIDATOR_TEST_ANCESTRY - - TEST_ORG_ID=$_VALIDATOR_TEST_ORG - args: - - $_PR_NUMBER - - $COMMIT_SHA - - $BUILD_ID - - $PROJECT_ID - - "19" # Build step - - terraform-google-conversion + # - name: 'gcr.io/graphite-docker-images/go-plus' + # id: tgc-test-integration-0.13.7 + # entrypoint: '/workspace/.ci/scripts/go-plus/terraform-validator-tester-integration/test_terraform_validator_integration.sh' + # allowFailure: true + # secretEnv: ["GITHUB_TOKEN"] + # waitFor: ["tpgb-head", "tpgb-base", "tgc-head", "tgc-base"] + # env: + # - TERRAFORM_VERSION=0.13.7 + # - TEST_PROJECT=$_VALIDATOR_TEST_PROJECT + # - TEST_FOLDER_ID=$_VALIDATOR_TEST_FOLDER + # - TEST_ANCESTRY=$_VALIDATOR_TEST_ANCESTRY + # - TEST_ORG_ID=$_VALIDATOR_TEST_ORG + # args: + # - $_PR_NUMBER + # - $COMMIT_SHA + # - $BUILD_ID + # - $PROJECT_ID + # - "19" # Build step + # - terraform-google-conversion - name: 'gcr.io/graphite-docker-images/bash-plus' id: tpgb-test diff --git a/mmv1/api/resource.rb b/mmv1/api/resource.rb index 0321f88f89f5..0670658de06d 100644 --- a/mmv1/api/resource.rb +++ b/mmv1/api/resource.rb @@ -394,8 +394,11 @@ def all_resourcerefs # At Create, they have no value but they can just be read in anyways, and after a Read # they will need to be set in every Update. def settable_properties - all_user_properties.reject { |v| v.output && !v.is_a?(Api::Type::Fingerprint) } - .reject(&:url_param_only) + settable_properties = all_user_properties.reject do |v| + v.output && !v.is_a?(Api::Type::Fingerprint) && !v.is_a?(Api::Type::KeyValueTerraformLabels) + end + settable_properties.reject(&:url_param_only) + .reject { |v| v.is_a?(Api::Type::KeyValueLabels) } end # Properties that will be returned in the API body @@ -448,14 +451,26 @@ def decoder? !@transport&.decoder.nil? end - def add_labels_related_fields(props) + def add_labels_related_fields(props, parent) props.each do |p| if p.is_a? Api::Type::KeyValueLabels + # The terraform_labels field is used to write to API, instead of the labels field. + p.ignore_write = true + + @custom_diff ||= [] + if parent.nil? + @custom_diff.append('tpgresource.SetTerraformLabelsDiff') + elsif parent == 'metadata' + @custom_diff.append('tpgresource.SetMetadataTerraformLabelsDiff') + end + + props << build_terraform_labels_field('labels', p.field_min_version, p.update_verb, + p.update_url) props << build_effective_labels_field('labels', p.field_min_version) elsif p.is_a? Api::Type::KeyValueAnnotations props << build_effective_labels_field('annotations', p.field_min_version) elsif (p.is_a? Api::Type::NestedObject) && !p.all_properties.nil? - p.properties = add_labels_related_fields(p.all_properties) + p.properties = add_labels_related_fields(p.all_properties, p.name) end end props @@ -467,7 +482,7 @@ def build_effective_labels_field(name, min_version) other clients and services." Api::Type::KeyValuePairs.new( - name: "effective_#{name}", + name: "effective#{name.capitalize}", output: true, api_name: name, description:, @@ -476,6 +491,21 @@ def build_effective_labels_field(name, min_version) ) end + def build_terraform_labels_field(name, min_version, update_verb, update_url) + description = "The combination of #{name} configured directly on the resource + and default #{name} configured on the provider." + + Api::Type::KeyValueTerraformLabels.new( + name: "terraform#{name.capitalize}", + output: true, + api_name: name, + description:, + min_version:, + update_verb:, + update_url: + ) + end + # ==================== # Version-related methods # ==================== diff --git a/mmv1/api/type.rb b/mmv1/api/type.rb index d8b505199993..b2959da9aed9 100644 --- a/mmv1/api/type.rb +++ b/mmv1/api/type.rb @@ -766,10 +766,10 @@ def exclude_if_not_in_version!(version) # in Map. class KeyValuePairs < Composite # Ignore writing the "effective_labels" and "effective_annotations" fields to API. - attr_reader :ignore_write + attr_accessor :ignore_write def initialize(name: nil, output: nil, api_name: nil, description: nil, min_version: nil, - ignore_write: nil) + ignore_write: nil, update_verb: nil, update_url: nil) super() @name = name @@ -778,6 +778,8 @@ def initialize(name: nil, output: nil, api_name: nil, description: nil, min_vers @description = description @min_version = min_version @ignore_write = ignore_write + @update_verb = update_verb + @update_url = update_url end def validate @@ -801,6 +803,10 @@ def validate end end + # An array of string -> string key -> value pairs used for the "terraform_labels" field. + class KeyValueTerraformLabels < KeyValuePairs + end + # An array of string -> string key -> value pairs used specifically for the "annotations" field. # The field name with this type should be "annotations" literally. class KeyValueAnnotations < KeyValuePairs diff --git a/mmv1/compiler.rb b/mmv1/compiler.rb index 0ca7dc22b610..609552842899 100755 --- a/mmv1/compiler.rb +++ b/mmv1/compiler.rb @@ -223,7 +223,9 @@ end res_yaml = File.read(file_path) resource = Api::Compiler.new(res_yaml).run - resource.properties = resource.add_labels_related_fields(resource.properties_with_excluded) + resource.properties = resource.add_labels_related_fields( + resource.properties_with_excluded, nil + ) resource.validate resources.push(resource) end diff --git a/mmv1/products/compute/ForwardingRule.yaml b/mmv1/products/compute/ForwardingRule.yaml index 15acdafc7c78..771626523dec 100644 --- a/mmv1/products/compute/ForwardingRule.yaml +++ b/mmv1/products/compute/ForwardingRule.yaml @@ -503,7 +503,7 @@ properties: send_empty_value: true update_verb: :PATCH update_url: projects/{{project}}/regions/{{region}}/forwardingRules/{{name}} - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Labels to apply to this forwarding rule. A list of key->value pairs. diff --git a/mmv1/products/compute/GlobalAddress.yaml b/mmv1/products/compute/GlobalAddress.yaml index b5cd3bd89ca5..320460dc8f7f 100644 --- a/mmv1/products/compute/GlobalAddress.yaml +++ b/mmv1/products/compute/GlobalAddress.yaml @@ -86,7 +86,7 @@ properties: characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. required: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Labels to apply to this address. A list of key->value pairs. diff --git a/mmv1/products/compute/GlobalForwardingRule.yaml b/mmv1/products/compute/GlobalForwardingRule.yaml index ee6df3585dfd..780dc6e8a562 100644 --- a/mmv1/products/compute/GlobalForwardingRule.yaml +++ b/mmv1/products/compute/GlobalForwardingRule.yaml @@ -296,7 +296,7 @@ properties: values: - :IPV4 - :IPV6 - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Labels to apply to this forwarding rule. A list of key->value pairs. diff --git a/mmv1/products/compute/VpnTunnel.yaml b/mmv1/products/compute/VpnTunnel.yaml index 3020328720d5..f1724d01ef68 100644 --- a/mmv1/products/compute/VpnTunnel.yaml +++ b/mmv1/products/compute/VpnTunnel.yaml @@ -230,7 +230,7 @@ properties: is_set: true default_from_api: true item_type: Api::Type::String - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: Labels to apply to this VpnTunnel. update_verb: :POST diff --git a/mmv1/provider/core.rb b/mmv1/provider/core.rb index fb66cbbc4377..a5651ec92ae2 100644 --- a/mmv1/provider/core.rb +++ b/mmv1/provider/core.rb @@ -401,7 +401,8 @@ def field_specific_update_methods(properties) # method and group them by update url & verb. def properties_by_custom_update(properties) update_props = properties.reject do |p| - p.update_url.nil? || p.update_verb.nil? || p.update_verb == :NOOP + p.update_url.nil? || p.update_verb.nil? || p.update_verb == :NOOP || + p.is_a?(Api::Type::KeyValueLabels) end update_props.group_by do |p| diff --git a/mmv1/provider/terraform.rb b/mmv1/provider/terraform.rb index 1cf370b33667..5d9cb7a4a696 100644 --- a/mmv1/provider/terraform.rb +++ b/mmv1/provider/terraform.rb @@ -92,6 +92,7 @@ def tf_types Api::Type::Array => 'schema.TypeList', Api::Type::KeyValuePairs => 'schema.TypeMap', Api::Type::KeyValueLabels => 'schema.TypeMap', + Api::Type::KeyValueTerraformLabels => 'schema.TypeMap', Api::Type::KeyValueAnnotations => 'schema.TypeMap', Api::Type::Map => 'schema.TypeSet', Api::Type::Fingerprint => 'schema.TypeString' diff --git a/mmv1/templates/terraform/examples/base_configs/test_file.go.erb b/mmv1/templates/terraform/examples/base_configs/test_file.go.erb index ab2ed99c2be9..3e9b14c491df 100644 --- a/mmv1/templates/terraform/examples/base_configs/test_file.go.erb +++ b/mmv1/templates/terraform/examples/base_configs/test_file.go.erb @@ -44,7 +44,7 @@ object.examples test_slug = "#{resource_name}_#{example.name.camelize(:lower)}Example" ignore_read = object.all_user_properties - .select{|p| p.url_param_only || p.ignore_read || p.is_a?(Api::Type::ResourceRef) || p.is_a?(Api::Type::KeyValueLabels || p.is_a?(Api::Type::KeyValueAnnotations))} + .select{|p| p.url_param_only || p.ignore_read || p.is_a?(Api::Type::ResourceRef) || p.is_a?(Api::Type::KeyValueLabels) || p.is_a?(Api::Type::KeyValueAnnotations) || p.is_a?(Api::Type::KeyValueTerraformLabels)} .map { |p| p.name.underscore } .concat(example.ignore_read_extra) diff --git a/mmv1/templates/terraform/flatten_property_method.erb b/mmv1/templates/terraform/flatten_property_method.erb index 5f8fdb875590..e19121c4f953 100644 --- a/mmv1/templates/terraform/flatten_property_method.erb +++ b/mmv1/templates/terraform/flatten_property_method.erb @@ -94,7 +94,7 @@ func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d }) } return transformed -<% elsif (property.is_a?(Api::Type::KeyValueLabels)) || (property.is_a?(Api::Type::KeyValueAnnotations)) -%> +<% elsif (property.is_a?(Api::Type::KeyValueLabels)) || (property.is_a?(Api::Type::KeyValueAnnotations)) || property.name == "terraformLabels" -%> if v == nil { return v } diff --git a/mmv1/templates/terraform/post_create/labels.erb b/mmv1/templates/terraform/post_create/labels.erb index e725830eaabd..f47ed50f122c 100644 --- a/mmv1/templates/terraform/post_create/labels.erb +++ b/mmv1/templates/terraform/post_create/labels.erb @@ -1,5 +1,6 @@ <% if properties.any?{ |p| p.name == "labels" } -%> -if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { +if v, ok := d.GetOkExists("terraform_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + labels := d.Get("labels") // Labels cannot be set in a create. We'll have to set them here. err = resource<%= resource_name -%>Read(d, meta) if err != nil { @@ -7,8 +8,8 @@ if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v } obj := make(map[string]interface{}) - // d.Get("labels") will have been overridden by the Read call. - labelsProp, err := expand<%= resource_name -%>Labels(v, d, config) + // d.Get("terraform_labels") will have been overridden by the Read call. + labelsProp, err := expand<%= resource_name -%>TerraformLabels(v, d, config) if err != nil { return err } @@ -47,8 +48,13 @@ if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v } // Set back the labels field, as it is needed to decide the value of "labels" in the state in the read function. - if err := d.Set("labels", v); err != nil { + if err := d.Set("labels", labels); err != nil { return fmt.Errorf("Error setting back labels: %s", err) } + + // Set back the terraform_labels field, as it is needed to decide the value of "terraform_labels" in the state in the read function. + if err := d.Set("terraform_labels", v); err != nil { + return fmt.Errorf("Error setting back terraform_labels: %s", err) + } } <% end -%> diff --git a/mmv1/third_party/terraform/fwmodels/provider_model.go.erb b/mmv1/third_party/terraform/fwmodels/provider_model.go.erb index 9d16de58a938..cba7e8f8f5c8 100644 --- a/mmv1/third_party/terraform/fwmodels/provider_model.go.erb +++ b/mmv1/third_party/terraform/fwmodels/provider_model.go.erb @@ -21,6 +21,7 @@ type ProviderModel struct { UserProjectOverride types.Bool `tfsdk:"user_project_override"` RequestTimeout types.String `tfsdk:"request_timeout"` RequestReason types.String `tfsdk:"request_reason"` + DefaultLabels types.Map `tfsdk:"default_labels"` // Generated Products <% products.each do |product| -%> diff --git a/mmv1/third_party/terraform/fwprovider/framework_provider.go.erb b/mmv1/third_party/terraform/fwprovider/framework_provider.go.erb index 803fb435c023..1805877939e9 100644 --- a/mmv1/third_party/terraform/fwprovider/framework_provider.go.erb +++ b/mmv1/third_party/terraform/fwprovider/framework_provider.go.erb @@ -113,6 +113,10 @@ func (p *FrameworkProvider) Schema(_ context.Context, _ provider.SchemaRequest, "request_reason": schema.StringAttribute{ Optional: true, }, + "default_labels": schema.MapAttribute{ + Optional: true, + ElementType: types.StringType, + }, // Generated Products <% products.each do |product| -%> diff --git a/mmv1/third_party/terraform/provider/provider.go.erb b/mmv1/third_party/terraform/provider/provider.go.erb index 8f86f3905ca9..28ef411adc91 100644 --- a/mmv1/third_party/terraform/provider/provider.go.erb +++ b/mmv1/third_party/terraform/provider/provider.go.erb @@ -143,6 +143,12 @@ func Provider() *schema.Provider { Optional: true, }, + "default_labels": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + // Generated Products <% products.each do |product| -%> "<%= product[:definitions].name.underscore -%>_custom_endpoint": { @@ -715,6 +721,13 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr config.Scopes[i] = scope.(string) } + config.DefaultLabels = make(map[string]string) + defaultLabels := d.Get("default_labels").(map[string]interface{}) + + for k, v := range defaultLabels { + config.DefaultLabels[k] = v.(string) + } + batchCfg, err := transport_tpg.ExpandProviderBatchingConfig(d.Get("batching")) if err != nil { return nil, diag.FromErr(err) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_dataset_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_dataset_test.go index 9bdb54d0502a..e7aa05f777d4 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_dataset_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_dataset_test.go @@ -51,7 +51,7 @@ func TestAccBigQueryDataset_basic(t *testing.T) { ImportStateVerify: true, // The labels field in the state is decided by the configuration. // During importing, the configuration is unavailable, so the labels field in the state after importing is empty. - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccBigQueryDatasetUpdated(datasetID), @@ -69,7 +69,7 @@ func TestAccBigQueryDataset_basic(t *testing.T) { ResourceName: "google_bigquery_dataset.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccBigQueryDatasetUpdated2(datasetID), @@ -78,7 +78,7 @@ func TestAccBigQueryDataset_basic(t *testing.T) { ResourceName: "google_bigquery_dataset.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccBigQueryDataset_withoutLabels(datasetID), @@ -156,7 +156,7 @@ func TestAccBigQueryDataset_datasetWithContents(t *testing.T) { ResourceName: "google_bigquery_dataset.contents_test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"delete_contents_on_destroy", "labels"}, + ImportStateVerifyIgnore: []string{"delete_contents_on_destroy", "labels", "terraform_labels"}, }, }, }) @@ -181,7 +181,7 @@ func TestAccBigQueryDataset_access(t *testing.T) { ResourceName: "google_bigquery_dataset.access_test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccBigQueryDatasetWithTwoAccess(datasetID), @@ -190,7 +190,7 @@ func TestAccBigQueryDataset_access(t *testing.T) { ResourceName: "google_bigquery_dataset.access_test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccBigQueryDatasetWithOneAccess(datasetID), @@ -199,7 +199,7 @@ func TestAccBigQueryDataset_access(t *testing.T) { ResourceName: "google_bigquery_dataset.access_test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccBigQueryDatasetWithViewAccess(datasetID, otherDatasetID, otherTableID), @@ -208,7 +208,7 @@ func TestAccBigQueryDataset_access(t *testing.T) { ResourceName: "google_bigquery_dataset.access_test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) @@ -231,7 +231,7 @@ func TestAccBigQueryDataset_regionalLocation(t *testing.T) { ResourceName: "google_bigquery_dataset.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) @@ -277,7 +277,7 @@ func TestAccBigQueryDataset_storageBillModel(t *testing.T) { ResourceName: "google_bigquery_dataset.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_address_test.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_address_test.go.erb index 79b9187aae5f..a637c410ab46 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_address_test.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_address_test.go.erb @@ -98,7 +98,7 @@ func TestAccComputeAddress_networkTier_withLabels(t *testing.T) { ImportStateVerify: true, // The labels field in the state is decided by the configuration. // During importing, the configuration is unavailable, so the labels field in the state after importing is empty. - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccComputeAddress_networkTier_withLabelsUpdate(acctest.RandString(t, 10)), @@ -116,7 +116,7 @@ func TestAccComputeAddress_networkTier_withLabels(t *testing.T) { ResourceName: "google_compute_address.foobar", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), @@ -173,6 +173,121 @@ func TestAccComputeAddress_networkTier_withProvider5(t *testing.T) { }) } +func TestAccComputeAddress_withProviderDefaultLabels(t *testing.T) { + // The test failed if VCR testing is enabled, because the cached provider config is used. + // With the cached provider config, any changes in the provider default labels will not be applied. + acctest.SkipIfVcr(t) + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeAddressDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeAddress_withProviderDefaultLabels(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_key1", "default_value1"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, + }, + { + Config: testAccComputeAddress_resourceLabelsOverridesProviderDefaultLabels(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "3"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "3600000"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_key1", "value1"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + // The labels field in the state is decided by the configuration. + // During importing, the configuration is unavailable, so the labels field in the state after importing is empty. + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, + }, + { + Config: testAccComputeAddress_moveResourceLabelToProviderDefaultLabels(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "2"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "3600000"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_key1", "value1"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, + }, + { + Config: testAccComputeAddress_resourceLabelsOverridesProviderDefaultLabels(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.%", "3"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_expiration_ms", "3600000"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_key1", "value1"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.env", "foo"), + resource.TestCheckResourceAttr("google_compute_address.foobar", "terraform_labels.default_expiration_ms", "3600000"), + + resource.TestCheckResourceAttr("google_compute_address.foobar", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, + }, + { + Config: testAccComputeAddress_networkTier(acctest.RandString(t, 10)), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "labels.%"), + resource.TestCheckNoResourceAttr("google_compute_address.foobar", "effective_labels.%"), + ), + }, + { + ResourceName: "google_compute_address.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccComputeAddress_networkTier_withLabels(i string) string { return fmt.Sprintf(` resource "google_compute_address" "foobar" { @@ -180,7 +295,7 @@ resource "google_compute_address" "foobar" { network_tier = "STANDARD" labels = { - env = "foo" + env = "foo" default_expiration_ms = 3600000 } } @@ -194,12 +309,74 @@ resource "google_compute_address" "foobar" { network_tier = "STANDARD" labels = { - env = "bar" + env = "bar" default_expiration_ms = 7200000 } } `, i) } + +func testAccComputeAddress_withProviderDefaultLabels(i string) string { + return fmt.Sprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + } +} + +resource "google_compute_address" "foobar" { + name = "tf-test-address-%s" + network_tier = "STANDARD" + + labels = { + env = "foo" + default_expiration_ms = 3600000 + } +} +`, i) +} + +func testAccComputeAddress_resourceLabelsOverridesProviderDefaultLabels(i string) string { + return fmt.Sprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + } +} + +resource "google_compute_address" "foobar" { + name = "tf-test-address-%s" + network_tier = "STANDARD" + + labels = { + env = "foo" + default_expiration_ms = 3600000 + default_key1 = "value1" + } +} +`, i) +} + +func testAccComputeAddress_moveResourceLabelToProviderDefaultLabels(i string) string { + return fmt.Sprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + env = "foo" + } +} + +resource "google_compute_address" "foobar" { + name = "tf-test-address-%s" + network_tier = "STANDARD" + + labels = { + default_expiration_ms = 3600000 + default_key1 = "value1" + } +} +`, i) +} <% end -%> func testAccComputeAddress_internal(i string) string { diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_forwarding_rule_test.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_forwarding_rule_test.go.erb index c8c34d473848..7b51fbabddbf 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_forwarding_rule_test.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_forwarding_rule_test.go.erb @@ -27,6 +27,7 @@ func TestAccComputeForwardingRule_update(t *testing.T) { ResourceName: "google_compute_forwarding_rule.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, resource.TestStep{ Config: testAccComputeForwardingRule_update(poolName, ruleName), @@ -35,6 +36,7 @@ func TestAccComputeForwardingRule_update(t *testing.T) { ResourceName: "google_compute_forwarding_rule.foobar", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_global_forwarding_rule_test.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_global_forwarding_rule_test.go.erb index 364a2583e48c..e4f0036ae180 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_global_forwarding_rule_test.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_global_forwarding_rule_test.go.erb @@ -108,7 +108,7 @@ func TestAccComputeGlobalForwardingRule_labels(t *testing.T) { ResourceName: "google_compute_global_forwarding_rule.forwarding_rule", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"port_range", "target"}, + ImportStateVerifyIgnore: []string{"port_range", "target", "labels", "terraform_labels"}, }, { Config: testAccComputeGlobalForwardingRule_labelsUpdated(fr, proxy, backend, hc, urlmap), @@ -117,7 +117,7 @@ func TestAccComputeGlobalForwardingRule_labels(t *testing.T) { ResourceName: "google_compute_global_forwarding_rule.forwarding_rule", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"port_range", "target"}, + ImportStateVerifyIgnore: []string{"port_range", "target", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/tpgresource/labels.go b/mmv1/third_party/terraform/tpgresource/labels.go new file mode 100644 index 000000000000..e18d1323c890 --- /dev/null +++ b/mmv1/third_party/terraform/tpgresource/labels.go @@ -0,0 +1,61 @@ +package tpgresource + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func SetTerraformLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { + config := meta.(*transport_tpg.Config) + + // Merge provider default labels with the user defined labels in the resource to get terraform managed labels + terraformLabels := make(map[string]string) + for k, v := range config.DefaultLabels { + terraformLabels[k] = v + } + + labels := d.Get("labels").(map[string]interface{}) + for k, v := range labels { + terraformLabels[k] = v.(string) + } + + if err := d.SetNew("terraform_labels", terraformLabels); err != nil { + return fmt.Errorf("error setting new terraform_labels diff: %w", err) + } + + return nil +} + +func SetMetadataTerraformLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { + v := d.Get("metadata") + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil + } + + config := meta.(*transport_tpg.Config) + + // Merge provider default labels with the user defined labels in the resource to get terraform managed labels + terraformLabels := make(map[string]string) + for k, v := range config.DefaultLabels { + terraformLabels[k] = v + } + + labels := d.Get("metadata.0.labels").(map[string]interface{}) + for k, v := range labels { + terraformLabels[k] = v.(string) + } + + raw := l[0] + original := raw.(map[string]interface{}) + original["terraform_labels"] = terraformLabels + + if err := d.SetNew("metadata", []interface{}{original}); err != nil { + return fmt.Errorf("error setting new metadata diff: %w", err) + } + + return nil +} diff --git a/mmv1/third_party/terraform/transport/config.go.erb b/mmv1/third_party/terraform/transport/config.go.erb index ee330cd4a26d..9e831c7d392b 100644 --- a/mmv1/third_party/terraform/transport/config.go.erb +++ b/mmv1/third_party/terraform/transport/config.go.erb @@ -189,6 +189,7 @@ type Config struct { UserProjectOverride bool RequestReason string RequestTimeout time.Duration + DefaultLabels map[string]string // PollInterval is passed to resource.StateChangeConf in common_operation.go // It controls the interval at which we poll for successful operations PollInterval time.Duration diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json index 9249c8265cf9..1daf2ee28ffd 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json @@ -22,6 +22,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "timeouts": null } @@ -52,6 +55,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "timeouts": null }, @@ -62,6 +68,7 @@ "etag": true, "id": true, "labels": {}, + "terraform_labels": {}, "last_modified_time": true, "project": true, "self_link": true diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json index d3a1e114db80..7519ca4bd735 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json @@ -21,6 +21,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "project": "{{.Provider.project}}", "timeouts": null @@ -61,6 +64,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "project": "{{.Provider.project}}", "timeouts": null @@ -72,6 +78,7 @@ "etag": true, "id": true, "labels": {}, + "terraform_labels": {}, "last_modified_time": true, "self_link": true } diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json index 5848f267fdd9..6b0d5a89ce54 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json @@ -21,6 +21,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "project": "{{.Provider.project}}", "timeouts": null @@ -61,6 +64,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "project": "{{.Provider.project}}", "timeouts": null @@ -72,6 +78,7 @@ "etag": true, "id": true, "labels": {}, + "terraform_labels": {}, "last_modified_time": true, "self_link": true } diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json index 6a19eeda793f..1725f40b59c3 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json @@ -21,6 +21,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "project": "{{.Provider.project}}", "timeouts": null @@ -59,6 +62,9 @@ "labels": { "env": "dev" }, + "terraform_labels": { + "env": "dev" + }, "location": "EU", "project": "{{.Provider.project}}", "timeouts": null @@ -70,6 +76,7 @@ "etag": true, "id": true, "labels": {}, + "terraform_labels": {}, "last_modified_time": true, "self_link": true } From fb61cfbb8adaf9b4517d3fb66223dcde9360cb06 Mon Sep 17 00:00:00 2001 From: pengq-google Date: Wed, 6 Sep 2023 15:14:25 -0400 Subject: [PATCH 023/476] Change the default value of unique_writer_identity in resource logging_project_sink to true. (#8875) --- .../logging/resource_logging_project_sink.go | 6 ++- .../resource_logging_project_sink_test.go | 50 ++++++++----------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/mmv1/third_party/terraform/services/logging/resource_logging_project_sink.go b/mmv1/third_party/terraform/services/logging/resource_logging_project_sink.go index 18b235c9b095..ced0bea2cb43 100644 --- a/mmv1/third_party/terraform/services/logging/resource_logging_project_sink.go +++ b/mmv1/third_party/terraform/services/logging/resource_logging_project_sink.go @@ -1,3 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package logging import ( @@ -36,9 +38,9 @@ func ResourceLoggingProjectSink() *schema.Resource { schm.Schema["unique_writer_identity"] = &schema.Schema{ Type: schema.TypeBool, Optional: true, - Default: false, + Default: true, ForceNew: true, - Description: `Whether or not to create a unique identity associated with this sink. If false (the default), then the writer_identity used is serviceAccount:cloud-logs@system.gserviceaccount.com. If true, then a unique service account is created and used for this sink. If you wish to publish logs across projects, you must set unique_writer_identity to true.`, + Description: `Whether or not to create a unique identity associated with this sink. If false (the legacy behavior), then the writer_identity used is serviceAccount:cloud-logs@system.gserviceaccount.com. If true, then a unique service account is created and used for this sink. If you wish to publish logs across projects, you must set unique_writer_identity to true.`, } return schm } diff --git a/mmv1/third_party/terraform/services/logging/resource_logging_project_sink_test.go b/mmv1/third_party/terraform/services/logging/resource_logging_project_sink_test.go index 2c5a08926abd..9cd468c45323 100644 --- a/mmv1/third_party/terraform/services/logging/resource_logging_project_sink_test.go +++ b/mmv1/third_party/terraform/services/logging/resource_logging_project_sink_test.go @@ -292,13 +292,11 @@ func testAccLoggingProjectSink_basic(name, project, bucketName string) string { resource "google_logging_project_sink" "basic" { name = "%s" project = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" - - unique_writer_identity = false } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -310,14 +308,12 @@ func testAccLoggingProjectSink_described(name, project, bucketName string) strin resource "google_logging_project_sink" "described" { name = "%s" project = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" description = "this is a description for a project level logging sink" - - unique_writer_identity = false } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -329,14 +325,12 @@ func testAccLoggingProjectSink_described_update(name, project, bucketName string resource "google_logging_project_sink" "described" { name = "%s" project = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" description = "description updated" - - unique_writer_identity = false } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -348,14 +342,14 @@ func testAccLoggingProjectSink_disabled(name, project, bucketName string) string resource "google_logging_project_sink" "disabled" { name = "%s" project = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" disabled = true unique_writer_identity = false } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -367,14 +361,14 @@ func testAccLoggingProjectSink_disabled_update(name, project, bucketName, disabl resource "google_logging_project_sink" "disabled" { name = "%s" project = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" disabled = "%s" unique_writer_identity = true } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -385,13 +379,13 @@ func testAccLoggingProjectSink_uniqueWriter(name, bucketName string) string { return fmt.Sprintf(` resource "google_logging_project_sink" "unique_writer" { name = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=ERROR" unique_writer_identity = true } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -402,13 +396,13 @@ func testAccLoggingProjectSink_uniqueWriterUpdated(name, bucketName string) stri return fmt.Sprintf(` resource "google_logging_project_sink" "unique_writer" { name = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=WARNING" unique_writer_identity = true } -resource "google_storage_bucket" "log-bucket" { +resource "google_storage_bucket" "gcs-bucket" { name = "%s" location = "US" } @@ -420,7 +414,7 @@ func testAccLoggingProjectSink_heredoc(name, project, bucketName string) string resource "google_logging_project_sink" "heredoc" { name = "%s" project = "%s" - destination = "storage.googleapis.com/${google_storage_bucket.log-bucket.name}" + destination = "storage.googleapis.com/${google_storage_bucket.gcs-bucket.name}" filter = <=ERROR" unique_writer_identity = true @@ -454,7 +448,7 @@ resource "google_logging_project_sink" "bigquery" { } } -resource "google_bigquery_dataset" "logging_sink" { +resource "google_bigquery_dataset" "bq_dataset" { dataset_id = "%s" description = "Log sink (generated during acc test of terraform-provider-google(-beta))." } @@ -465,13 +459,11 @@ func testAccLoggingProjectSink_bigquery_after(sinkName, bqDatasetID string) stri return fmt.Sprintf(` resource "google_logging_project_sink" "bigquery" { name = "%s" - destination = "bigquery.googleapis.com/projects/%s/datasets/${google_bigquery_dataset.logging_sink.dataset_id}" + destination = "bigquery.googleapis.com/projects/%s/datasets/${google_bigquery_dataset.bq_dataset.dataset_id}" filter = "logName=\"projects/%s/logs/compute.googleapis.com%%2Factivity_log\" AND severity>=WARNING" - - unique_writer_identity = false } -resource "google_bigquery_dataset" "logging_sink" { +resource "google_bigquery_dataset" "bq_dataset" { dataset_id = "%s" description = "Log sink (generated during acc test of terraform-provider-google(-beta))." } @@ -495,8 +487,6 @@ resource "google_logging_project_sink" "loggingbucket" { description = "test-2" filter = "resource.type = k8s_container" } - - unique_writer_identity = true } `, name, project, project) From 665f32fdaad358725d781df4bd919e22b90eaaab Mon Sep 17 00:00:00 2001 From: Charles Leon Date: Thu, 7 Sep 2023 10:01:21 -0700 Subject: [PATCH 024/476] Change several fields in Access Context Manager from list to set (#8788) Co-authored-by: Charles Leon --- .../ServicePerimeter.yaml | 16 ++ .../ServicePerimeters.yaml | 18 ++- ...text_manager_service_perimeter_test.go.erb | 102 ++++++++++++ ...ontext_manager_services_perimeters_test.go | 145 +++++++++++++++++- 4 files changed, 277 insertions(+), 4 deletions(-) diff --git a/mmv1/products/accesscontextmanager/ServicePerimeter.yaml b/mmv1/products/accesscontextmanager/ServicePerimeter.yaml index 96c2bf0b5b86..dfeb24421dbf 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeter.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeter.yaml @@ -157,6 +157,7 @@ properties: - status.0.access_levels - status.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'accessLevels' description: | @@ -175,6 +176,7 @@ properties: - status.0.access_levels - status.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'restrictedServices' description: | @@ -236,6 +238,7 @@ properties: - !ruby/object:Api::Type::Array name: 'identities' item_type: Api::Type::String + is_set: true description: | A list of identities that are allowed access through this ingress policy. Should be in the format of email address. The email address should represent @@ -275,6 +278,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, protected by this `ServicePerimeter` @@ -348,6 +352,7 @@ properties: A list of identities that are allowed access through this `EgressPolicy`. Should be in the format of email address. The email address should represent individual user or service account only. + is_set: true item_type: Api::Type::String - !ruby/object:Api::Type::NestedObject name: 'egressTo' @@ -357,6 +362,7 @@ properties: properties: - !ruby/object:Api::Type::Array name: 'resources' + is_set: true item_type: Api::Type::String description: | A list of resources, currently only projects in the form @@ -366,6 +372,7 @@ properties: the perimeter. - !ruby/object:Api::Type::Array name: 'externalResources' + is_set: true item_type: Api::Type::String description: | A list of external resources that are allowed to be accessed. A request @@ -423,6 +430,7 @@ properties: - spec.0.access_levels - spec.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'accessLevels' description: | @@ -441,6 +449,7 @@ properties: - spec.0.access_levels - spec.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'restrictedServices' description: | @@ -454,6 +463,7 @@ properties: - spec.0.access_levels - spec.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::NestedObject name: 'vpcAccessibleServices' description: | @@ -471,6 +481,7 @@ properties: The list of APIs usable within the Service Perimeter. Must be empty unless `enableRestriction` is True. item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'ingressPolicies' description: | @@ -500,6 +511,7 @@ properties: - !ruby/object:Api::Type::Array name: 'identities' item_type: Api::Type::String + is_set: true description: | A list of identities that are allowed access through this ingress policy. Should be in the format of email address. The email address should represent @@ -539,6 +551,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, protected by this `ServicePerimeter` @@ -613,6 +626,7 @@ properties: Should be in the format of email address. The email address should represent individual user or service account only. item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::NestedObject name: 'egressTo' description: | @@ -622,6 +636,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, that match this to stanza. A request matches @@ -631,6 +646,7 @@ properties: - !ruby/object:Api::Type::Array name: 'externalResources' item_type: Api::Type::String + is_set: true description: | A list of external resources that are allowed to be accessed. A request matches if it contains an external resource in this list (Example: diff --git a/mmv1/products/accesscontextmanager/ServicePerimeters.yaml b/mmv1/products/accesscontextmanager/ServicePerimeters.yaml index 72a41e289a0d..e4fb6867a3ca 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeters.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeters.yaml @@ -57,7 +57,6 @@ properties: name: 'servicePerimeters' description: | The desired Service Perimeters that should replace all existing Service Perimeters in the Access Policy. - is_set: true item_type: !ruby/object:Api::Type::NestedObject properties: - !ruby/object:Api::Type::String @@ -133,6 +132,7 @@ properties: # - status.0.access_levels # - status.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'accessLevels' description: | @@ -153,6 +153,7 @@ properties: # - status.0.access_levels # - status.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'restrictedServices' description: | @@ -194,6 +195,7 @@ properties: have multiple `IngressPolicies`, each of which is evaluated separately. Access is granted if any `Ingress Policy` grants it. Must be empty for a perimeter bridge. + is_set: true item_type: !ruby/object:Api::Type::NestedObject properties: - !ruby/object:Api::Type::NestedObject @@ -215,6 +217,7 @@ properties: - :ANY_SERVICE_ACCOUNT - !ruby/object:Api::Type::Array name: 'identities' + is_set: true item_type: Api::Type::String description: | A list of identities that are allowed access through this ingress policy. @@ -255,6 +258,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, protected by this `ServicePerimeter` @@ -328,6 +332,7 @@ properties: A list of identities that are allowed access through this `EgressPolicy`. Should be in the format of email address. The email address should represent individual user or service account only. + is_set: true item_type: Api::Type::String - !ruby/object:Api::Type::NestedObject name: 'egressTo' @@ -338,6 +343,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, that match this to stanza. A request matches @@ -347,6 +353,7 @@ properties: - !ruby/object:Api::Type::Array name: 'externalResources' item_type: Api::Type::String + is_set: true description: | A list of external resources that are allowed to be accessed. A request matches if it contains an external resource in this list (Example: @@ -404,9 +411,11 @@ properties: # - spec.0.resources # - spec.0.access_levels # - spec.0.restricted_services + is_set: true item_type: Api::Type::String - !ruby/object:Api::Type::Array name: 'accessLevels' + is_set: true description: | A list of AccessLevel resource names that allow resources within the ServicePerimeter to be accessed from the internet. @@ -440,6 +449,7 @@ properties: # - spec.0.access_levels # - spec.0.restricted_services item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::NestedObject name: 'vpcAccessibleServices' description: | @@ -457,6 +467,7 @@ properties: The list of APIs usable within the Service Perimeter. Must be empty unless `enableRestriction` is True. item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::Array name: 'ingressPolicies' description: | @@ -485,6 +496,7 @@ properties: - :ANY_SERVICE_ACCOUNT - !ruby/object:Api::Type::Array name: 'identities' + is_set: true item_type: Api::Type::String description: | A list of identities that are allowed access through this ingress policy. @@ -525,6 +537,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, protected by this `ServicePerimeter` @@ -599,6 +612,7 @@ properties: Should be in the format of email address. The email address should represent individual user or service account only. item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::NestedObject name: 'egressTo' description: | @@ -608,6 +622,7 @@ properties: - !ruby/object:Api::Type::Array name: 'resources' item_type: Api::Type::String + is_set: true description: | A list of resources, currently only projects in the form `projects/`, that match this to stanza. A request matches @@ -617,6 +632,7 @@ properties: - !ruby/object:Api::Type::Array name: 'externalResources' item_type: Api::Type::String + is_set: true description: | A list of external resources that are allowed to be accessed. A request matches if it contains an external resource in this list (Example: diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_test.go.erb b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_test.go.erb index 8e945af590f8..42849562162d 100644 --- a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_test.go.erb +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_service_perimeter_test.go.erb @@ -207,6 +207,83 @@ resource "google_access_context_manager_service_perimeter" "test-access" { name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/servicePerimeters/%s" title = "%s" perimeter_type = "PERIMETER_TYPE_REGULAR" + use_explicit_dry_run_spec = true + spec { + restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + access_levels = [google_access_context_manager_access_level.test-access.name] + + vpc_accessible_services { + enable_restriction = true + allowed_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + } + + ingress_policies { + ingress_from { + sources { + access_level = google_access_context_manager_access_level.test-access.name + } + identity_type = "ANY_IDENTITY" + } + + ingress_to { + resources = [ "*" ] + operations { + service_name = "bigquery.googleapis.com" + + method_selectors { + method = "BigQueryStorage.ReadRows" + } + + method_selectors { + method = "TableService.ListTables" + } + + method_selectors { + permission = "bigquery.jobs.get" + } + } + + operations { + service_name = "storage.googleapis.com" + + method_selectors { + method = "google.storage.objects.create" + } + } + } + } + ingress_policies { + ingress_from { + identities = ["user:test@google.com"] + } + ingress_to { + resources = ["*"] + } + } + + egress_policies { + egress_from { + identity_type = "ANY_USER_ACCOUNT" + } + egress_to { + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + permission = "externalResource.read" + } + } + external_resources = ["s3://bucket1"] + } + } + egress_policies { + egress_from { + identities = ["user:test@google.com"] + } + egress_to { + resources = ["*"] + } + } + } status { restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] access_levels = [google_access_context_manager_access_level.test-access.name] @@ -251,11 +328,36 @@ resource "google_access_context_manager_service_perimeter" "test-access" { } } } + ingress_policies { + ingress_from { + identities = ["user:test@google.com"] + } + ingress_to { + resources = ["*"] + } + } egress_policies { egress_from { identity_type = "ANY_USER_ACCOUNT" } + egress_to { + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + permission = "externalResource.read" + } + } + external_resources = ["s3://bucket1"] + } + } + egress_policies { + egress_from { + identities = ["user:test@google.com"] + } + egress_to { + resources = ["*"] + } } } } diff --git a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_services_perimeters_test.go b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_services_perimeters_test.go index d66bb2950e49..a220ea5a5e26 100644 --- a/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_services_perimeters_test.go +++ b/mmv1/third_party/terraform/services/accesscontextmanager/resource_access_context_manager_services_perimeters_test.go @@ -199,17 +199,156 @@ resource "google_access_context_manager_service_perimeters" "test-access" { name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/servicePerimeters/%s" title = "%s" perimeter_type = "PERIMETER_TYPE_REGULAR" + use_explicit_dry_run_spec = true + spec { + restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + access_levels = [google_access_context_manager_access_level.test-access.name] + + vpc_accessible_services { + enable_restriction = true + allowed_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + } + + ingress_policies { + ingress_from { + sources { + access_level = google_access_context_manager_access_level.test-access.name + } + identity_type = "ANY_IDENTITY" + } + + ingress_to { + resources = [ "*" ] + operations { + service_name = "bigquery.googleapis.com" + + method_selectors { + method = "BigQueryStorage.ReadRows" + } + + method_selectors { + method = "TableService.ListTables" + } + + method_selectors { + permission = "bigquery.jobs.get" + } + } + + operations { + service_name = "storage.googleapis.com" + + method_selectors { + method = "google.storage.objects.create" + } + } + } + } + ingress_policies { + ingress_from { + identities = ["user:test@google.com"] + } + ingress_to { + resources = ["*"] + } + } + + egress_policies { + egress_from { + identity_type = "ANY_USER_ACCOUNT" + } + egress_to { + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + permission = "externalResource.read" + } + } + external_resources = ["s3://bucket1"] + } + } + egress_policies { + egress_from { + identities = ["user:test@google.com"] + } + egress_to { + resources = ["*"] + } + } + } status { - restricted_services = ["bigquery.googleapis.com"] + restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + access_levels = [google_access_context_manager_access_level.test-access.name] + + vpc_accessible_services { + enable_restriction = true + allowed_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + } + + ingress_policies { + ingress_from { + sources { + access_level = google_access_context_manager_access_level.test-access.name + } + identity_type = "ANY_IDENTITY" + } + + ingress_to { + resources = [ "*" ] + operations { + service_name = "bigquery.googleapis.com" + + method_selectors { + method = "BigQueryStorage.ReadRows" + } + + method_selectors { + method = "TableService.ListTables" + } + + method_selectors { + permission = "bigquery.jobs.get" + } + } + + operations { + service_name = "storage.googleapis.com" + + method_selectors { + method = "google.storage.objects.create" + } + } + } + } + ingress_policies { + ingress_from { + identities = ["user:test@google.com"] + } + ingress_to { + resources = ["*"] + } + } + egress_policies { + egress_from { + identity_type = "ANY_USER_ACCOUNT" + } egress_to { - external_resources = ["s3://bucket2"] operations { service_name = "bigquery.googleapis.com" method_selectors { - method = "*" + permission = "externalResource.read" } } + external_resources = ["s3://bucket1"] + } + } + egress_policies { + egress_from { + identities = ["user:test@google.com"] + } + egress_to { + resources = ["*"] } } } From 1a3c02a61619b69a355c2930779dedf33dd6dc28 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Thu, 7 Sep 2023 10:52:16 -0700 Subject: [PATCH 025/476] Use Create instead of Patch to create google_service_networking_connection (#8872) * Use Create instead of Patch to create google_service_networking_connection * Remove bootstraped networks for service networking connection * Use resource google_compute_network for tests * Fix tests --- mmv1/products/alloydb/Backup.yaml | 4 - mmv1/products/alloydb/Instance.yaml | 2 - .../connectionprofile.yaml | 2 - mmv1/products/looker/Instance.yaml | 1 - mmv1/products/memcache/Instance.yaml | 2 - mmv1/products/redis/Instance.yaml | 2 - .../examples/alloydb_backup_basic.tf.erb | 8 +- .../examples/alloydb_backup_full.tf.erb | 8 +- .../examples/alloydb_instance_basic.tf.erb | 8 +- ..._service_connection_profile_alloydb.tf.erb | 8 +- .../looker_instance_enterprise_full.tf.erb | 8 +- .../examples/memcache_instance_basic.tf.erb | 6 +- .../redis_instance_private_service.tf.erb | 8 +- .../alloydb/resource_alloydb_backup_test.go | 33 +++---- .../resource_alloydb_cluster_restore_test.go | 88 +++++++++---------- .../alloydb/resource_alloydb_instance_test.go | 61 ++++++------- ...esource_cloudbuild_worker_pool_test.go.erb | 10 +-- .../resource_cloudids_endpoint_test.go | 18 ++-- .../resource_memcache_instance_test.go | 14 +-- .../resource_service_networking_connection.go | 19 +--- .../resource_sql_database_instance_test.go | 54 ++++++------ 21 files changed, 171 insertions(+), 193 deletions(-) diff --git a/mmv1/products/alloydb/Backup.yaml b/mmv1/products/alloydb/Backup.yaml index 3d4ac4cbf1c8..36a9f4339914 100644 --- a/mmv1/products/alloydb/Backup.yaml +++ b/mmv1/products/alloydb/Backup.yaml @@ -42,8 +42,6 @@ examples: alloydb_cluster_name: 'alloydb-cluster' alloydb_instance_name: 'alloydb-instance' network_name: 'alloydb-network' - test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "alloydb-backup-basic")' ignore_read_extra: - 'reconciling' - 'update_time' @@ -55,8 +53,6 @@ examples: alloydb_cluster_name: 'alloydb-cluster' alloydb_instance_name: 'alloydb-instance' network_name: 'alloydb-network' - test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "alloydb-backup-full")' ignore_read_extra: - 'reconciling' - 'update_time' diff --git a/mmv1/products/alloydb/Instance.yaml b/mmv1/products/alloydb/Instance.yaml index a8929b3965c7..5530c7434fa0 100644 --- a/mmv1/products/alloydb/Instance.yaml +++ b/mmv1/products/alloydb/Instance.yaml @@ -57,8 +57,6 @@ examples: alloydb_cluster_name: 'alloydb-cluster' alloydb_instance_name: 'alloydb-instance' network_name: 'alloydb-network' - test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "alloydb-instance-basic")' ignore_read_extra: - 'reconciling' - 'update_time' diff --git a/mmv1/products/databasemigrationservice/connectionprofile.yaml b/mmv1/products/databasemigrationservice/connectionprofile.yaml index 3396127ae17b..62e6fc778024 100644 --- a/mmv1/products/databasemigrationservice/connectionprofile.yaml +++ b/mmv1/products/databasemigrationservice/connectionprofile.yaml @@ -87,8 +87,6 @@ examples: profile: 'my-profileid' global_address_name: 'private-ip-alloc' network_name: 'vpc-network' - test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "profile-alloydb")' parameters: - !ruby/object:Api::Type::String name: 'connectionProfileId' diff --git a/mmv1/products/looker/Instance.yaml b/mmv1/products/looker/Instance.yaml index 7e645702f776..b830b54c7ac8 100644 --- a/mmv1/products/looker/Instance.yaml +++ b/mmv1/products/looker/Instance.yaml @@ -57,7 +57,6 @@ examples: client_id: 'my-client-id' client_secret: 'my-client-secret' test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "looker-instance-enterprise")' kms_key_name: 'acctest.BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name' parameters: - !ruby/object:Api::Type::String diff --git a/mmv1/products/memcache/Instance.yaml b/mmv1/products/memcache/Instance.yaml index 11637e7d1cd4..a3dd514aa13f 100644 --- a/mmv1/products/memcache/Instance.yaml +++ b/mmv1/products/memcache/Instance.yaml @@ -37,8 +37,6 @@ examples: instance_name: 'test-instance' network_name: 'test-network' address_name: 'address' - test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "memcache-instance-basic")' parameters: - !ruby/object:Api::Type::String name: 'region' diff --git a/mmv1/products/redis/Instance.yaml b/mmv1/products/redis/Instance.yaml index b232ae4e69bd..e49c6e3ee36c 100644 --- a/mmv1/products/redis/Instance.yaml +++ b/mmv1/products/redis/Instance.yaml @@ -67,8 +67,6 @@ examples: instance_name: 'private-cache' address_name: 'address' network_name: 'redis-test-network' - test_vars_overrides: - network_name: 'acctest.BootstrapSharedTestNetwork(t, "redis-private-service")' - !ruby/object:Provider::Terraform::Examples name: 'redis_instance_mrr' primary_resource_id: 'cache' diff --git a/mmv1/templates/terraform/examples/alloydb_backup_basic.tf.erb b/mmv1/templates/terraform/examples/alloydb_backup_basic.tf.erb index 418ccb67c8ed..41521891bfec 100644 --- a/mmv1/templates/terraform/examples/alloydb_backup_basic.tf.erb +++ b/mmv1/templates/terraform/examples/alloydb_backup_basic.tf.erb @@ -9,7 +9,7 @@ resource "google_alloydb_backup" "<%= ctx[:primary_resource_id] %>" { resource "google_alloydb_cluster" "<%= ctx[:primary_resource_id] %>" { cluster_id = "<%= ctx[:vars]['alloydb_cluster_name'] %>" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "<%= ctx[:primary_resource_id] %>" { @@ -25,15 +25,15 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "<%= ctx[:vars]['network_name'] %>" } diff --git a/mmv1/templates/terraform/examples/alloydb_backup_full.tf.erb b/mmv1/templates/terraform/examples/alloydb_backup_full.tf.erb index bb280b783894..cb4e7b45bfde 100644 --- a/mmv1/templates/terraform/examples/alloydb_backup_full.tf.erb +++ b/mmv1/templates/terraform/examples/alloydb_backup_full.tf.erb @@ -13,7 +13,7 @@ resource "google_alloydb_backup" "<%= ctx[:primary_resource_id] %>" { resource "google_alloydb_cluster" "<%= ctx[:primary_resource_id] %>" { cluster_id = "<%= ctx[:vars]['alloydb_cluster_name'] %>" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "<%= ctx[:primary_resource_id] %>" { @@ -29,15 +29,15 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "<%= ctx[:vars]['network_name'] %>" } diff --git a/mmv1/templates/terraform/examples/alloydb_instance_basic.tf.erb b/mmv1/templates/terraform/examples/alloydb_instance_basic.tf.erb index f6907cd44237..479245a01cb2 100644 --- a/mmv1/templates/terraform/examples/alloydb_instance_basic.tf.erb +++ b/mmv1/templates/terraform/examples/alloydb_instance_basic.tf.erb @@ -13,7 +13,7 @@ resource "google_alloydb_instance" "<%= ctx[:primary_resource_id] %>" { resource "google_alloydb_cluster" "<%= ctx[:primary_resource_id] %>" { cluster_id = "<%= ctx[:vars]['alloydb_cluster_name'] %>" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id initial_user { password = "<%= ctx[:vars]['alloydb_cluster_name'] %>" @@ -22,7 +22,7 @@ resource "google_alloydb_cluster" "<%= ctx[:primary_resource_id] %>" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "<%= ctx[:vars]['network_name'] %>" } @@ -31,11 +31,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/database_migration_service_connection_profile_alloydb.tf.erb b/mmv1/templates/terraform/examples/database_migration_service_connection_profile_alloydb.tf.erb index 68a6ea686b57..96384e6e4b58 100644 --- a/mmv1/templates/terraform/examples/database_migration_service_connection_profile_alloydb.tf.erb +++ b/mmv1/templates/terraform/examples/database_migration_service_connection_profile_alloydb.tf.erb @@ -1,7 +1,7 @@ data "google_project" "project" { } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "<%= ctx[:vars]['network_name'] %>" } @@ -10,11 +10,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -34,7 +34,7 @@ resource "google_database_migration_service_connection_profile" "<%= ctx[:primar user = "alloyuser%{random_suffix}" password = "alloypass%{random_suffix}" } - vpc_network = data.google_compute_network.default.id + vpc_network = google_compute_network.default.id labels = { alloyfoo = "alloybar" } diff --git a/mmv1/templates/terraform/examples/looker_instance_enterprise_full.tf.erb b/mmv1/templates/terraform/examples/looker_instance_enterprise_full.tf.erb index 5a223f1e21db..54d74ad63d8e 100644 --- a/mmv1/templates/terraform/examples/looker_instance_enterprise_full.tf.erb +++ b/mmv1/templates/terraform/examples/looker_instance_enterprise_full.tf.erb @@ -5,7 +5,7 @@ resource "google_looker_instance" "<%= ctx[:primary_resource_id] %>" { private_ip_enabled = true public_ip_enabled = false reserved_range = "${google_compute_global_address.looker_range.name}" - consumer_network = data.google_compute_network.looker_network.id + consumer_network = google_compute_network.looker_network.id admin_settings { allowed_email_domains = ["google.com"] } @@ -49,7 +49,7 @@ resource "google_looker_instance" "<%= ctx[:primary_resource_id] %>" { } resource "google_service_networking_connection" "looker_vpc_connection" { - network = data.google_compute_network.looker_network.id + network = google_compute_network.looker_network.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.looker_range.name] } @@ -59,12 +59,12 @@ resource "google_compute_global_address" "looker_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 20 - network = data.google_compute_network.looker_network.id + network = google_compute_network.looker_network.id } data "google_project" "project" {} -data "google_compute_network" "looker_network" { +resource "google_compute_network" "looker_network" { name = "<%= ctx[:vars]["network_name"] %>" } diff --git a/mmv1/templates/terraform/examples/memcache_instance_basic.tf.erb b/mmv1/templates/terraform/examples/memcache_instance_basic.tf.erb index e021bacf3d63..0ad8d19378fd 100644 --- a/mmv1/templates/terraform/examples/memcache_instance_basic.tf.erb +++ b/mmv1/templates/terraform/examples/memcache_instance_basic.tf.erb @@ -6,7 +6,7 @@ // If this network hasn't been created and you are using this example in your // config, add an additional network resource or change // this from "data"to "resource" -data "google_compute_network" "memcache_network" { +resource "google_compute_network" "memcache_network" { name = "<%= ctx[:vars]['network_name'] %>" } @@ -15,11 +15,11 @@ resource "google_compute_global_address" "service_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.memcache_network.id + network = google_compute_network.memcache_network.id } resource "google_service_networking_connection" "private_service_connection" { - network = data.google_compute_network.memcache_network.id + network = google_compute_network.memcache_network.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.service_range.name] } diff --git a/mmv1/templates/terraform/examples/redis_instance_private_service.tf.erb b/mmv1/templates/terraform/examples/redis_instance_private_service.tf.erb index 800df78e22aa..90e0e4ff5698 100644 --- a/mmv1/templates/terraform/examples/redis_instance_private_service.tf.erb +++ b/mmv1/templates/terraform/examples/redis_instance_private_service.tf.erb @@ -6,7 +6,7 @@ // If this network hasn't been created and you are using this example in your // config, add an additional network resource or change // this from "data"to "resource" -data "google_compute_network" "redis-network" { +resource "google_compute_network" "redis-network" { name = "<%= ctx[:vars]['network_name'] %>" } @@ -15,11 +15,11 @@ resource "google_compute_global_address" "service_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.redis-network.id + network = google_compute_network.redis-network.id } resource "google_service_networking_connection" "private_service_connection" { - network = data.google_compute_network.redis-network.id + network = google_compute_network.redis-network.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.service_range.name] } @@ -32,7 +32,7 @@ resource "google_redis_instance" "<%= ctx[:primary_resource_id] %>" { location_id = "us-central1-a" alternative_location_id = "us-central1-f" - authorized_network = data.google_compute_network.redis-network.id + authorized_network = google_compute_network.redis-network.id connect_mode = "PRIVATE_SERVICE_ACCESS" redis_version = "REDIS_4_0" diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go index 4da0e5c86fa7..33091f142314 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go @@ -10,9 +10,10 @@ import ( func TestAccAlloydbBackup_update(t *testing.T) { t.Parallel() + random_suffix := acctest.RandString(t, 10) context := map[string]interface{}{ - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydb-backup-update"), - "random_suffix": acctest.RandString(t, 10), + "network_name": "tf-test-alloydb-network" + random_suffix, + "random_suffix": random_suffix, } acctest.VcrTest(t, resource.TestCase{ @@ -61,7 +62,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "default" { @@ -77,16 +78,16 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } `, context) @@ -98,7 +99,7 @@ func TestAccAlloydbBackup_createBackupWithMandatoryFields(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbbackup-mandatory"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -125,12 +126,12 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "default" { location = "us-central1" cluster_id = "tf-test-alloydb-cluster%{random_suffix}" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } data "google_project" "project" { } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -147,7 +148,7 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id lifecycle { ignore_changes = [ address, @@ -161,7 +162,7 @@ resource "google_compute_global_address" "private_ip_alloc" { } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -172,7 +173,7 @@ func TestAccAlloydbBackup_usingCMEK(t *testing.T) { t.Parallel() context := map[string]interface{}{ - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydb-backup-cmek"), + "network_name": "tf-test-" + acctest.RandString(t, 10), "random_suffix": acctest.RandString(t, 10), "key_name": "tf-test-key-" + acctest.RandString(t, 10), } @@ -215,7 +216,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "default" { @@ -231,16 +232,16 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } data "google_project" "project" {} diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_restore_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_restore_test.go index d6def69f6832..9e3d209581e0 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_restore_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_restore_test.go @@ -19,7 +19,7 @@ func TestAccAlloydbCluster_restore(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-restore"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -86,7 +86,7 @@ func testAccAlloydbClusterAndInstanceAndBackup(context map[string]interface{}) s resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -107,7 +107,7 @@ resource "google_alloydb_backup" "default" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -116,11 +116,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -133,7 +133,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_OnlyOneSourceAllowed(context map[ resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -155,7 +155,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "restored" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_backup_source { backup_name = google_alloydb_backup.default.name } @@ -171,7 +171,7 @@ resource "google_alloydb_cluster" "restored" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -180,11 +180,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -197,7 +197,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_SourceClusterAndPointInTimeRequir resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -219,7 +219,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "restored" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_continuous_backup_source { cluster = google_alloydb_cluster.source.name @@ -232,7 +232,7 @@ resource "google_alloydb_cluster" "restored" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -241,11 +241,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -257,7 +257,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_RestoredFromBackup(context map[st resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -279,7 +279,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "restored_from_backup" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_backup_source { backup_name = google_alloydb_backup.default.name } @@ -291,7 +291,7 @@ resource "google_alloydb_cluster" "restored_from_backup" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -300,11 +300,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -318,7 +318,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_RestoredFromBackupAndRestoredFrom resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -340,7 +340,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "restored_from_backup" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_backup_source { backup_name = google_alloydb_backup.default.name } @@ -353,7 +353,7 @@ resource "google_alloydb_cluster" "restored_from_backup" { resource "google_alloydb_cluster" "restored_from_point_in_time" { cluster_id = "tf-test-alloydb-pitr-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_continuous_backup_source { cluster = google_alloydb_cluster.source.name point_in_time = google_alloydb_backup.default.update_time @@ -366,7 +366,7 @@ resource "google_alloydb_cluster" "restored_from_point_in_time" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -375,11 +375,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -393,7 +393,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_RestoredFromBackupAndRestoredFrom resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -415,7 +415,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "restored_from_backup" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_backup_source { backup_name = google_alloydb_backup.default.name } @@ -433,7 +433,7 @@ resource "google_alloydb_cluster" "restored_from_backup" { resource "google_alloydb_cluster" "restored_from_point_in_time" { cluster_id = "tf-test-alloydb-pitr-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_continuous_backup_source { cluster = google_alloydb_cluster.source.name point_in_time = google_alloydb_backup.default.update_time @@ -451,7 +451,7 @@ resource "google_alloydb_cluster" "restored_from_point_in_time" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -460,11 +460,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -478,7 +478,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_RestoredFromBackupAndRestoredFrom resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -508,7 +508,7 @@ resource "google_alloydb_backup" "default2" { resource "google_alloydb_cluster" "restored_from_backup" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_backup_source { backup_name = google_alloydb_backup.default2.name } @@ -528,7 +528,7 @@ resource "google_alloydb_cluster" "restored_from_backup" { resource "google_alloydb_cluster" "restored_from_point_in_time" { cluster_id = "tf-test-alloydb-pitr-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_continuous_backup_source { cluster = google_alloydb_cluster.restored_from_backup.name point_in_time = google_alloydb_backup.default.update_time @@ -546,7 +546,7 @@ resource "google_alloydb_cluster" "restored_from_point_in_time" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -555,11 +555,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -573,7 +573,7 @@ func testAccAlloydbClusterAndInstanceAndBackup_RestoredFromBackupAndRestoredFrom resource "google_alloydb_cluster" "source" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_alloydb_instance" "source" { @@ -595,7 +595,7 @@ resource "google_alloydb_backup" "default" { resource "google_alloydb_cluster" "restored_from_backup" { cluster_id = "tf-test-alloydb-backup-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_backup_source { backup_name = google_alloydb_backup.default.name } @@ -604,7 +604,7 @@ resource "google_alloydb_cluster" "restored_from_backup" { resource "google_alloydb_cluster" "restored_from_point_in_time" { cluster_id = "tf-test-alloydb-pitr-restored-cluster-%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id restore_continuous_backup_source { cluster = google_alloydb_cluster.source.name point_in_time = google_alloydb_backup.default.update_time @@ -613,7 +613,7 @@ resource "google_alloydb_cluster" "restored_from_point_in_time" { data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -622,11 +622,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go index 944d04c25ad1..824bab8b12f0 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go @@ -10,9 +10,10 @@ import ( func TestAccAlloydbInstance_update(t *testing.T) { t.Parallel() + random_suffix := acctest.RandString(t, 10) context := map[string]interface{}{ - "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-update"), + "random_suffix": random_suffix, + "network_name": "tf-test-alloydb-network" + random_suffix, } acctest.VcrTest(t, resource.TestCase{ @@ -63,7 +64,7 @@ resource "google_alloydb_instance" "default" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id initial_user { password = "tf-test-alloydb-cluster%{random_suffix}" @@ -73,7 +74,7 @@ resource "google_alloydb_cluster" "default" { data "google_project" "project" { } -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -82,11 +83,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -99,7 +100,7 @@ func TestAccAlloydbInstance_createInstanceWithMandatoryFields(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-mandatory"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -127,12 +128,12 @@ resource "google_alloydb_instance" "default" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -141,11 +142,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -158,7 +159,7 @@ func TestAccAlloydbInstance_createInstanceWithMaximumFields(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-maximum"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -205,12 +206,12 @@ resource "google_alloydb_instance" "default" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -219,11 +220,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -236,7 +237,7 @@ func TestAccAlloydbInstance_createPrimaryAndReadPoolInstance(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-readpool"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -273,12 +274,12 @@ resource "google_alloydb_instance" "read_pool" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -287,11 +288,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -304,7 +305,7 @@ func TestAccAlloydbInstance_updateDatabaseFlagInPrimaryInstance(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-updatedb"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -342,12 +343,12 @@ resource "google_alloydb_instance" "primary" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -356,11 +357,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } @@ -382,12 +383,12 @@ resource "google_alloydb_instance" "primary" { resource "google_alloydb_cluster" "default" { cluster_id = "tf-test-alloydb-cluster%{random_suffix}" location = "us-central1" - network = data.google_compute_network.default.id + network = google_compute_network.default.id } data "google_project" "project" {} -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } @@ -396,11 +397,11 @@ resource "google_compute_global_address" "private_ip_alloc" { address_type = "INTERNAL" purpose = "VPC_PEERING" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "vpc_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] } diff --git a/mmv1/third_party/terraform/services/cloudbuild/resource_cloudbuild_worker_pool_test.go.erb b/mmv1/third_party/terraform/services/cloudbuild/resource_cloudbuild_worker_pool_test.go.erb index 601dc86d27d9..6cc7a87dd96c 100644 --- a/mmv1/third_party/terraform/services/cloudbuild/resource_cloudbuild_worker_pool_test.go.erb +++ b/mmv1/third_party/terraform/services/cloudbuild/resource_cloudbuild_worker_pool_test.go.erb @@ -104,7 +104,7 @@ func TestAccCloudbuildWorkerPool_withNetwork(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), "project": envvar.GetTestProjectFromEnv(), - "network_name": acctest.BootstrapSharedTestNetwork(t, "cloudbuild-workerpool"), + "network_name": "tf-test-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -127,7 +127,7 @@ func TestAccCloudbuildWorkerPool_withNetwork(t *testing.T) { func testAccCloudbuildWorkerPool_withNetwork(context map[string]interface{}) string { return acctest.Nprintf(` -data "google_compute_network" "network" { +resource "google_compute_network" "network" { name = "%{network_name}" } @@ -136,11 +136,11 @@ resource "google_compute_global_address" "worker_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.network.id + network = google_compute_network.network.id } resource "google_service_networking_connection" "worker_pool_conn" { - network = data.google_compute_network.network.id + network = google_compute_network.network.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.worker_range.name] } @@ -154,7 +154,7 @@ resource "google_cloudbuild_worker_pool" "pool" { no_external_ip = false } network_config { - peered_network = data.google_compute_network.network.id + peered_network = google_compute_network.network.id peered_network_ip_range = "/29" } depends_on = [google_service_networking_connection.worker_pool_conn] diff --git a/mmv1/third_party/terraform/services/cloudids/resource_cloudids_endpoint_test.go b/mmv1/third_party/terraform/services/cloudids/resource_cloudids_endpoint_test.go index 65153dada11c..3e6f8a626c90 100644 --- a/mmv1/third_party/terraform/services/cloudids/resource_cloudids_endpoint_test.go +++ b/mmv1/third_party/terraform/services/cloudids/resource_cloudids_endpoint_test.go @@ -18,7 +18,7 @@ func TestAccCloudIdsEndpoint_basic(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), - "network_name": acctest.BootstrapSharedTestNetwork(t, "cloud-ids-endpoint"), + "network_name": "tf-test-key-" + acctest.RandString(t, 10), } acctest.VcrTest(t, resource.TestCase{ @@ -48,7 +48,7 @@ func TestAccCloudIdsEndpoint_basic(t *testing.T) { func testCloudIds_basic(context map[string]interface{}) string { return acctest.Nprintf(` -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } resource "google_compute_global_address" "service_range" { @@ -56,10 +56,10 @@ resource "google_compute_global_address" "service_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "private_service_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.service_range.name] } @@ -67,7 +67,7 @@ resource "google_service_networking_connection" "private_service_connection" { resource "google_cloud_ids_endpoint" "endpoint" { name = "cloud-ids-test-%{random_suffix}" location = "us-central1-f" - network = data.google_compute_network.default.id + network = google_compute_network.default.id severity = "INFORMATIONAL" threat_exceptions = ["12", "67"] depends_on = [google_service_networking_connection.private_service_connection] @@ -77,7 +77,7 @@ resource "google_cloud_ids_endpoint" "endpoint" { func testCloudIds_basicUpdate(context map[string]interface{}) string { return acctest.Nprintf(` -data "google_compute_network" "default" { +resource "google_compute_network" "default" { name = "%{network_name}" } resource "google_compute_global_address" "service_range" { @@ -85,10 +85,10 @@ resource "google_compute_global_address" "service_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.default.id + network = google_compute_network.default.id } resource "google_service_networking_connection" "private_service_connection" { - network = data.google_compute_network.default.id + network = google_compute_network.default.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.service_range.name] } @@ -96,7 +96,7 @@ resource "google_service_networking_connection" "private_service_connection" { resource "google_cloud_ids_endpoint" "endpoint" { name = "cloud-ids-test-%{random_suffix}" location = "us-central1-f" - network = data.google_compute_network.default.id + network = google_compute_network.default.id severity = "INFORMATIONAL" threat_exceptions = ["33"] depends_on = [google_service_networking_connection.private_service_connection] diff --git a/mmv1/third_party/terraform/services/memcache/resource_memcache_instance_test.go b/mmv1/third_party/terraform/services/memcache/resource_memcache_instance_test.go index 51b78686511e..7c42f5632e91 100644 --- a/mmv1/third_party/terraform/services/memcache/resource_memcache_instance_test.go +++ b/mmv1/third_party/terraform/services/memcache/resource_memcache_instance_test.go @@ -13,7 +13,7 @@ func TestAccMemcacheInstance_update(t *testing.T) { prefix := fmt.Sprintf("%d", acctest.RandInt(t)) name := fmt.Sprintf("tf-test-%s", prefix) - network := acctest.BootstrapSharedTestNetwork(t, "memcache-instance-update") + network := "tf-test-" + acctest.RandString(t, 10) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -47,11 +47,11 @@ resource "google_compute_global_address" "service_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.memcache_network.id + network = google_compute_network.memcache_network.id } resource "google_service_networking_connection" "private_service_connection" { - network = data.google_compute_network.memcache_network.id + network = google_compute_network.memcache_network.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.service_range.name] } @@ -75,7 +75,7 @@ resource "google_memcache_instance" "test" { } } -data "google_compute_network" "memcache_network" { +resource "google_compute_network" "memcache_network" { name = "%s" } `, prefix, name, network) @@ -88,11 +88,11 @@ resource "google_compute_global_address" "service_range" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.memcache_network.id + network = google_compute_network.memcache_network.id } resource "google_service_networking_connection" "private_service_connection" { - network = data.google_compute_network.memcache_network.id + network = google_compute_network.memcache_network.id service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.service_range.name] } @@ -116,7 +116,7 @@ resource "google_memcache_instance" "test" { } } -data "google_compute_network" "memcache_network" { +resource "google_compute_network" "memcache_network" { name = "%s" } `, prefix, name, network) diff --git a/mmv1/third_party/terraform/services/servicenetworking/resource_service_networking_connection.go b/mmv1/third_party/terraform/services/servicenetworking/resource_service_networking_connection.go index ac1ff4a07912..249b268ba58f 100644 --- a/mmv1/third_party/terraform/services/servicenetworking/resource_service_networking_connection.go +++ b/mmv1/third_party/terraform/services/servicenetworking/resource_service_networking_connection.go @@ -94,27 +94,16 @@ func resourceServiceNetworkingConnectionCreate(d *schema.ResourceData, meta inte project := networkFieldValue.Project parentService := formatParentService(d.Get("service").(string)) - // We use Patch instead of Create, because we're getting - // "Error waiting for Create Service Networking Connection: - // Error code 9, message: Cannot modify allocated ranges in - // CreateConnection. Please use UpdateConnection." - // if we're creating peerings to more than one VPC (like two - // CloudSQL instances within one project, peered with two - // clusters.) - // - // This is a workaround for: - // https://issuetracker.google.com/issues/131908322 - // - // The API docs don't specify that you can do connections/-, - // but that's what gcloud does, and it's easier than grabbing - // the connection name. + + // There is no blocker to use Create method, as the bug in CloudSQL has been fixed (https://b.corp.google.com/issues/123276199). + // Read more in https://stackoverflow.com/questions/55135559/unable-to-recreate-private-service-access-on-gcp // err == nil indicates that the billing_project value was found if bp, err := tpgresource.GetBillingProject(d, config); err == nil { project = bp } - createCall := config.NewServiceNetworkingClient(userAgent).Services.Connections.Patch(parentService+"/connections/-", connection).UpdateMask("reservedPeeringRanges").Force(true) + createCall := config.NewServiceNetworkingClient(userAgent).Services.Connections.Create(parentService, connection) if config.UserProjectOverride { createCall.Header().Add("X-Goog-User-Project", project) } diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go index 64607beb5cb0..fa295d443061 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go +++ b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go @@ -179,7 +179,7 @@ func TestAccSqlDatabaseInstance_deleteDefaultUserBeforeSubsequentApiCalls(t *tes databaseName := "tf-test-" + acctest.RandString(t, 10) addressName := "tf-test-" + acctest.RandString(t, 10) - networkName := acctest.BootstrapSharedTestNetwork(t, "sql-instance-private-network-clone-2") + networkName := "tf-test-" + acctest.RandString(t, 10) // 1. Create an instance. // 2. Add a root@'%' user. @@ -737,7 +737,7 @@ func TestAccSqlDatabaseInstance_withPrivateNetwork_withoutAllocatedIpRange(t *te databaseName := "tf-test-" + acctest.RandString(t, 10) addressName := "tf-test-" + acctest.RandString(t, 10) - networkName := acctest.BootstrapSharedTestNetwork(t, "sql-instance-private-network") + networkName := "tf-test-" + acctest.RandString(t, 10) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -970,9 +970,9 @@ func TestAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRange(t *testi databaseName := "tf-test-" + acctest.RandString(t, 10) addressName := "tf-test-" + acctest.RandString(t, 10) - networkName := acctest.BootstrapSharedTestNetwork(t, "sql-instance-private-network-allocated") + networkName := "tf-test-" + acctest.RandString(t, 10) addressName_update := "tf-test-" + acctest.RandString(t, 10) + "update" - networkName_update := acctest.BootstrapSharedTestNetwork(t, "sql-instance-private-network-allocated-update") + networkName_update := "tf-test-" + acctest.RandString(t, 10) + "update" acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -1007,7 +1007,7 @@ func TestAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRangeReplica(t databaseName := "tf-test-" + acctest.RandString(t, 10) addressName := "tf-test-" + acctest.RandString(t, 10) - networkName := acctest.BootstrapSharedTestNetwork(t, "sql-instance-private-network-replica") + networkName := "tf-test-" + acctest.RandString(t, 10) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -1039,7 +1039,7 @@ func TestAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRangeClone(t * databaseName := "tf-test-" + acctest.RandString(t, 10) addressName := "tf-test-" + acctest.RandString(t, 10) - networkName := acctest.BootstrapSharedTestNetwork(t, "sql-instance-private-network-clone") + networkName := "tf-test-" + acctest.RandString(t, 10) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -2798,7 +2798,7 @@ func testAccSqlDatabaseInstance_withPrivateNetwork_withoutAllocatedIpRange(datab } return fmt.Sprintf(` -data "google_compute_network" "servicenet" { +resource "google_compute_network" "servicenet" { name = "%s" } @@ -2807,11 +2807,11 @@ resource "google_compute_global_address" "foobar" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link } resource "google_service_networking_connection" "foobar" { - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.foobar.name] } @@ -2826,7 +2826,7 @@ resource "google_sql_database_instance" "instance" { tier = "db-f1-micro" ip_configuration { ipv4_enabled = "false" - private_network = data.google_compute_network.servicenet.self_link + private_network = google_compute_network.servicenet.self_link %s } } @@ -2836,7 +2836,7 @@ resource "google_sql_database_instance" "instance" { func testAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRange(databaseName, networkName, addressRangeName string) string { return fmt.Sprintf(` -data "google_compute_network" "servicenet" { +resource "google_compute_network" "servicenet" { name = "%s" } @@ -2845,11 +2845,11 @@ resource "google_compute_global_address" "foobar" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link } resource "google_service_networking_connection" "foobar" { - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.foobar.name] } @@ -2864,7 +2864,7 @@ resource "google_sql_database_instance" "instance" { tier = "db-f1-micro" ip_configuration { ipv4_enabled = "false" - private_network = data.google_compute_network.servicenet.self_link + private_network = google_compute_network.servicenet.self_link allocated_ip_range = google_compute_global_address.foobar.name } } @@ -2874,7 +2874,7 @@ resource "google_sql_database_instance" "instance" { func testAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRangeReplica(databaseName, networkName, addressRangeName string) string { return fmt.Sprintf(` -data "google_compute_network" "servicenet" { +resource "google_compute_network" "servicenet" { name = "%s" } @@ -2883,11 +2883,11 @@ resource "google_compute_global_address" "foobar" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link } resource "google_service_networking_connection" "foobar" { - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.foobar.name] } @@ -2902,7 +2902,7 @@ resource "google_sql_database_instance" "instance" { tier = "db-f1-micro" ip_configuration { ipv4_enabled = "false" - private_network = data.google_compute_network.servicenet.self_link + private_network = google_compute_network.servicenet.self_link } backup_configuration { enabled = true @@ -2921,7 +2921,7 @@ resource "google_sql_database_instance" "replica1" { tier = "db-f1-micro" ip_configuration { ipv4_enabled = "false" - private_network = data.google_compute_network.servicenet.self_link + private_network = google_compute_network.servicenet.self_link allocated_ip_range = google_compute_global_address.foobar.name } } @@ -2942,7 +2942,7 @@ resource "google_sql_database_instance" "replica1" { func testAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRangeClone(databaseName, networkName, addressRangeName string) string { return fmt.Sprintf(` -data "google_compute_network" "servicenet" { +resource "google_compute_network" "servicenet" { name = "%s" } @@ -2951,11 +2951,11 @@ resource "google_compute_global_address" "foobar" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link } resource "google_service_networking_connection" "foobar" { - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.foobar.name] } @@ -2970,7 +2970,7 @@ resource "google_sql_database_instance" "instance" { tier = "db-f1-micro" ip_configuration { ipv4_enabled = "false" - private_network = data.google_compute_network.servicenet.self_link + private_network = google_compute_network.servicenet.self_link } backup_configuration { enabled = true @@ -2997,7 +2997,7 @@ resource "google_sql_database_instance" "clone1" { func testAccSqlDatabaseInstance_withPrivateNetwork_withAllocatedIpRangeClone_withSettings(databaseName, networkName, addressRangeName string) string { return fmt.Sprintf(` -data "google_compute_network" "servicenet" { +resource "google_compute_network" "servicenet" { name = "%s" } @@ -3006,11 +3006,11 @@ resource "google_compute_global_address" "foobar" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link } resource "google_service_networking_connection" "foobar" { - network = data.google_compute_network.servicenet.self_link + network = google_compute_network.servicenet.self_link service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.foobar.name] } @@ -3025,7 +3025,7 @@ resource "google_sql_database_instance" "instance" { tier = "db-f1-micro" ip_configuration { ipv4_enabled = "false" - private_network = data.google_compute_network.servicenet.self_link + private_network = google_compute_network.servicenet.self_link } backup_configuration { enabled = true From 85bf78e0d6473af71141b65c869ac4168a2af7c7 Mon Sep 17 00:00:00 2001 From: Lingkai Shen Date: Thu, 7 Sep 2023 15:26:39 -0400 Subject: [PATCH 026/476] Remove firebase_project_location (#8783) --- mmv1/products/firebase/ProjectLocation.yaml | 58 ------------------- .../firebase_project_location_basic.tf.erb | 23 -------- 2 files changed, 81 deletions(-) delete mode 100644 mmv1/products/firebase/ProjectLocation.yaml delete mode 100644 mmv1/templates/terraform/examples/firebase_project_location_basic.tf.erb diff --git a/mmv1/products/firebase/ProjectLocation.yaml b/mmv1/products/firebase/ProjectLocation.yaml deleted file mode 100644 index e1957694e954..000000000000 --- a/mmv1/products/firebase/ProjectLocation.yaml +++ /dev/null @@ -1,58 +0,0 @@ -# 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: 'ProjectLocation' -min_version: beta -base_url: projects/{{project}} -self_link: projects/{{project}} -create_url: projects/{{project}}/defaultLocation:finalize -nested_query: !ruby/object:Api::Resource::NestedQuery - keys: - - resources -immutable: true -description: | - Sets the default Google Cloud Platform (GCP) resource location for the specified FirebaseProject. - This method creates an App Engine application with a default Cloud Storage bucket, located in the specified - locationId. This location must be one of the available GCP resource locations. - After the default GCP resource location is finalized, or if it was already set, it cannot be changed. - The default GCP resource location for the specified FirebaseProject might already be set because either the - GCP Project already has an App Engine application or defaultLocation.finalize was previously called with a - specified locationId. Any new calls to defaultLocation.finalize with a different specified locationId will - return a 409 error. -references: !ruby/object:Api::Resource::ReferenceLinks - guides: - 'Official Documentation': 'https://firebase.google.com/' - api: 'https://firebase.google.com/docs/reference/firebase-management/rest/v1beta1/projects.defaultLocation/finalize' -import_format: ['projects/{{project}}', '{{project}}'] -skip_delete: true -skip_sweeper: true -deprecation_message: >- - `google_firebase_project_location` is deprecated in favor of explicitly configuring `google_app_engine_application` - and `google_firestore_database`. This resource will be removed in the next major release of the provider. -examples: - - !ruby/object:Provider::Terraform::Examples - name: 'firebase_project_location_basic' - min_version: 'beta' - primary_resource_id: 'basic' - test_env_vars: - org_id: :ORG_ID - vars: - project_name: "my-project" -properties: - - !ruby/object:Api::Type::String - name: locationId - required: true - description: | - The ID of the default GCP resource location for the Project. The location must be one of the available GCP - resource locations. diff --git a/mmv1/templates/terraform/examples/firebase_project_location_basic.tf.erb b/mmv1/templates/terraform/examples/firebase_project_location_basic.tf.erb deleted file mode 100644 index 4cdebbe83a21..000000000000 --- a/mmv1/templates/terraform/examples/firebase_project_location_basic.tf.erb +++ /dev/null @@ -1,23 +0,0 @@ -resource "google_project" "default" { - provider = google-beta - - project_id = "<%= ctx[:vars]['project_name'] %>" - name = "<%= ctx[:vars]['project_name'] %>" - org_id = "<%= ctx[:test_env_vars]['org_id'] %>" - - labels = { - "firebase" = "enabled" - } -} - -resource "google_firebase_project" "default" { - provider = google-beta - project = google_project.default.project_id -} - -resource "google_firebase_project_location" "<%= ctx[:primary_resource_id] %>" { - provider = google-beta - project = google_firebase_project.default.project - - location_id = "us-central" -} From 186acac752c74d3cc6e716bd7c5ef06f1360d0ef Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Thu, 7 Sep 2023 14:15:36 -0700 Subject: [PATCH 027/476] Don't override Terraform unmanaged labels (#8881) * Don't override Terraform unmanaged labels * Merge labels customdiff functions --- mmv1/api/resource.rb | 73 +++++++++++++------ mmv1/api/type.rb | 5 ++ mmv1/products/alloydb/Instance.yaml | 4 +- mmv1/products/cloudrunv2/Service.yaml | 2 +- mmv1/products/containerattached/Cluster.yaml | 2 +- mmv1/provider/core.rb | 2 +- mmv1/provider/terraform.rb | 1 + .../terraform/flatten_property_method.erb | 2 +- .../terraform/post_create/labels.erb | 15 +++- .../alloydb/resource_alloydb_instance_test.go | 2 +- .../resource_cloud_run_v2_service_test.go | 16 ++-- ..._container_attached_cluster_update_test.go | 6 +- .../terraform/tpgresource/annotations.go | 58 +++++++++++++++ .../terraform/tpgresource/labels.go | 45 ++++++++++-- .../data/example_bigquery_dataset.tfplan.json | 7 ++ ...e_bigquery_dataset_iam_binding.tfplan.json | 7 ++ ...le_bigquery_dataset_iam_member.tfplan.json | 7 ++ ...le_bigquery_dataset_iam_policy.tfplan.json | 7 ++ 18 files changed, 209 insertions(+), 52 deletions(-) create mode 100644 mmv1/third_party/terraform/tpgresource/annotations.go diff --git a/mmv1/api/resource.rb b/mmv1/api/resource.rb index 0670658de06d..a0ae098eaad7 100644 --- a/mmv1/api/resource.rb +++ b/mmv1/api/resource.rb @@ -394,11 +394,13 @@ def all_resourcerefs # At Create, they have no value but they can just be read in anyways, and after a Read # they will need to be set in every Update. def settable_properties - settable_properties = all_user_properties.reject do |v| - v.output && !v.is_a?(Api::Type::Fingerprint) && !v.is_a?(Api::Type::KeyValueTerraformLabels) + props = all_user_properties.reject do |v| + v.output && !v.is_a?(Api::Type::Fingerprint) && !v.is_a?(Api::Type::KeyValueEffectiveLabels) + end + props = props.reject(&:url_param_only) + props.reject do |v| + v.is_a?(Api::Type::KeyValueLabels) || v.is_a?(Api::Type::KeyValueAnnotations) end - settable_properties.reject(&:url_param_only) - .reject { |v| v.is_a?(Api::Type::KeyValueLabels) } end # Properties that will be returned in the API body @@ -454,21 +456,9 @@ def decoder? def add_labels_related_fields(props, parent) props.each do |p| if p.is_a? Api::Type::KeyValueLabels - # The terraform_labels field is used to write to API, instead of the labels field. - p.ignore_write = true - - @custom_diff ||= [] - if parent.nil? - @custom_diff.append('tpgresource.SetTerraformLabelsDiff') - elsif parent == 'metadata' - @custom_diff.append('tpgresource.SetMetadataTerraformLabelsDiff') - end - - props << build_terraform_labels_field('labels', p.field_min_version, p.update_verb, - p.update_url) - props << build_effective_labels_field('labels', p.field_min_version) + add_labels_fields(props, parent, p) elsif p.is_a? Api::Type::KeyValueAnnotations - props << build_effective_labels_field('annotations', p.field_min_version) + add_annotations_fields(props, parent, p) elsif (p.is_a? Api::Type::NestedObject) && !p.all_properties.nil? p.properties = add_labels_related_fields(p.all_properties, p.name) end @@ -476,22 +466,58 @@ def add_labels_related_fields(props, parent) props end - def build_effective_labels_field(name, min_version) + def add_labels_fields(props, parent, labels) + # The effective_labels field is used to write to API, instead of the labels field. + labels.ignore_write = true + + @custom_diff ||= [] + if parent.nil? + @custom_diff.append('tpgresource.SetLabelsDiff') + elsif parent == 'metadata' + @custom_diff.append('tpgresource.SetMetadataLabelsDiff') + end + + props << build_terraform_labels_field('labels', labels.field_min_version) + props << build_effective_labels_field( + 'labels', labels.field_min_version, labels.update_verb, labels.update_url + ) + end + + def add_annotations_fields(props, parent, annotations) + # The effective_annotations field is used to write to API, + # instead of the annotations field. + annotations.ignore_write = true + + @custom_diff ||= [] + if parent.nil? + @custom_diff.append('tpgresource.SetAnnotationsDiff') + elsif parent == 'metadata' + @custom_diff.append('tpgresource.SetMetadataAnnotationsDiff') + end + + props << build_effective_labels_field( + 'annotations', annotations.field_min_version, + annotations.update_verb, annotations.update_url + ) + end + + def build_effective_labels_field(name, min_version, update_verb, update_url) description = "All of #{name} (key/value pairs)\ present on the resource in GCP, including the #{name} configured through Terraform,\ other clients and services." - Api::Type::KeyValuePairs.new( + Api::Type::KeyValueEffectiveLabels.new( name: "effective#{name.capitalize}", output: true, api_name: name, description:, min_version:, - ignore_write: true + update_verb:, + update_url: ) end - def build_terraform_labels_field(name, min_version, update_verb, update_url) + def build_terraform_labels_field(name, min_version) description = "The combination of #{name} configured directly on the resource and default #{name} configured on the provider." @@ -501,8 +527,7 @@ def build_terraform_labels_field(name, min_version, update_verb, update_url) api_name: name, description:, min_version:, - update_verb:, - update_url: + ignore_write: true ) end diff --git a/mmv1/api/type.rb b/mmv1/api/type.rb index b2959da9aed9..c9b385e6b4b6 100644 --- a/mmv1/api/type.rb +++ b/mmv1/api/type.rb @@ -807,6 +807,11 @@ def validate class KeyValueTerraformLabels < KeyValuePairs end + # An array of string -> string key -> value pairs used for the "effective_labels" + # and "effective_annotations" fields. + class KeyValueEffectiveLabels < KeyValuePairs + end + # An array of string -> string key -> value pairs used specifically for the "annotations" field. # The field name with this type should be "annotations" literally. class KeyValueAnnotations < KeyValuePairs diff --git a/mmv1/products/alloydb/Instance.yaml b/mmv1/products/alloydb/Instance.yaml index 5530c7434fa0..972aaa4e079f 100644 --- a/mmv1/products/alloydb/Instance.yaml +++ b/mmv1/products/alloydb/Instance.yaml @@ -99,10 +99,10 @@ properties: output: true description: | The system-generated UID of the resource. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'User-defined labels for the alloydb instance.' - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: 'annotations' description: 'Annotations to allow client tools to store small amount of arbitrary diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index dc5a781d36cf..db919ee81e51 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -152,7 +152,7 @@ properties: Cloud Run API v2 does not support labels with `run.googleapis.com`, `cloud.googleapis.com`, `serving.knative.dev`, or `autoscaling.knative.dev` namespaces, and they will be rejected. All system labels in v1 now have a corresponding field in v2 Service. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: 'annotations' description: |- Unstructured key value map that may be set by external tools to store and arbitrary metadata. They are not queryable and should be preserved when modifying objects. diff --git a/mmv1/products/containerattached/Cluster.yaml b/mmv1/products/containerattached/Cluster.yaml index 3d64fa3485b5..96acf1f86b14 100644 --- a/mmv1/products/containerattached/Cluster.yaml +++ b/mmv1/products/containerattached/Cluster.yaml @@ -202,7 +202,7 @@ properties: description: | The Kubernetes version of the cluster. output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: annotations description: | Optional. Annotations on the cluster. This field has the same diff --git a/mmv1/provider/core.rb b/mmv1/provider/core.rb index a5651ec92ae2..0cdf06f8c4e9 100644 --- a/mmv1/provider/core.rb +++ b/mmv1/provider/core.rb @@ -402,7 +402,7 @@ def field_specific_update_methods(properties) def properties_by_custom_update(properties) update_props = properties.reject do |p| p.update_url.nil? || p.update_verb.nil? || p.update_verb == :NOOP || - p.is_a?(Api::Type::KeyValueLabels) + p.is_a?(Api::Type::KeyValueLabels) # effective_labels is used for update end update_props.group_by do |p| diff --git a/mmv1/provider/terraform.rb b/mmv1/provider/terraform.rb index 5d9cb7a4a696..4b89fb535374 100644 --- a/mmv1/provider/terraform.rb +++ b/mmv1/provider/terraform.rb @@ -93,6 +93,7 @@ def tf_types Api::Type::KeyValuePairs => 'schema.TypeMap', Api::Type::KeyValueLabels => 'schema.TypeMap', Api::Type::KeyValueTerraformLabels => 'schema.TypeMap', + Api::Type::KeyValueEffectiveLabels => 'schema.TypeMap', Api::Type::KeyValueAnnotations => 'schema.TypeMap', Api::Type::Map => 'schema.TypeSet', Api::Type::Fingerprint => 'schema.TypeString' diff --git a/mmv1/templates/terraform/flatten_property_method.erb b/mmv1/templates/terraform/flatten_property_method.erb index e19121c4f953..f13a7d670744 100644 --- a/mmv1/templates/terraform/flatten_property_method.erb +++ b/mmv1/templates/terraform/flatten_property_method.erb @@ -94,7 +94,7 @@ func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d }) } return transformed -<% elsif (property.is_a?(Api::Type::KeyValueLabels)) || (property.is_a?(Api::Type::KeyValueAnnotations)) || property.name == "terraformLabels" -%> +<% elsif (property.is_a?(Api::Type::KeyValueLabels)) || (property.is_a?(Api::Type::KeyValueAnnotations)) || (property.is_a?(Api::Type::KeyValueTerraformLabels)) -%> if v == nil { return v } diff --git a/mmv1/templates/terraform/post_create/labels.erb b/mmv1/templates/terraform/post_create/labels.erb index f47ed50f122c..1aaf5c26ce90 100644 --- a/mmv1/templates/terraform/post_create/labels.erb +++ b/mmv1/templates/terraform/post_create/labels.erb @@ -1,6 +1,8 @@ <% if properties.any?{ |p| p.name == "labels" } -%> -if v, ok := d.GetOkExists("terraform_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { +if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { labels := d.Get("labels") + terraformLables := d.Get("terraform_labels") + // Labels cannot be set in a create. We'll have to set them here. err = resource<%= resource_name -%>Read(d, meta) if err != nil { @@ -8,8 +10,8 @@ if v, ok := d.GetOkExists("terraform_labels"); !tpgresource.IsEmptyValue(reflect } obj := make(map[string]interface{}) - // d.Get("terraform_labels") will have been overridden by the Read call. - labelsProp, err := expand<%= resource_name -%>TerraformLabels(v, d, config) + // d.Get("effective_labels") will have been overridden by the Read call. + labelsProp, err := expand<%= resource_name -%>EffectiveLabels(v, d, config) if err != nil { return err } @@ -53,8 +55,13 @@ if v, ok := d.GetOkExists("terraform_labels"); !tpgresource.IsEmptyValue(reflect } // Set back the terraform_labels field, as it is needed to decide the value of "terraform_labels" in the state in the read function. - if err := d.Set("terraform_labels", v); err != nil { + if err := d.Set("terraform_labels", terraformLables); err != nil { return fmt.Errorf("Error setting back terraform_labels: %s", err) } + + // Set back the effective_labels field, as it is needed to decide the value of "effective_labels" in the state in the read function. + if err := d.Set("effective_labels", v); err != nil { + return fmt.Errorf("Error setting back effective_labels: %s", err) + } } <% end -%> diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go index 824bab8b12f0..52c40c4efb5b 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go @@ -37,7 +37,7 @@ func TestAccAlloydbInstance_update(t *testing.T) { ResourceName: "google_alloydb_instance.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"cluster", "instance_id", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"cluster", "instance_id", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go index 00ddd0472239..feb6bfbd9959 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go @@ -30,7 +30,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, { Config: testAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(context), @@ -39,7 +39,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, }, }) @@ -227,7 +227,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceTCPProbesUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, { Config: testAccCloudRunV2Service_cloudrunv2ServiceUpdateWithTCPStartupProbeAndHTTPLivenessProbe(context), @@ -236,7 +236,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceTCPProbesUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, }, }) @@ -261,7 +261,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceHTTPProbesUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, { Config: testAccCloudRunV2Service_cloudrunv2ServiceUpdateWithHTTPStartupProbe(context), @@ -270,7 +270,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceHTTPProbesUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, }, }) @@ -296,7 +296,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceGRPCProbesUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, { Config: testAccCloudRunV2Service_cloudRunServiceUpdateWithGRPCLivenessProbe(context), @@ -305,7 +305,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceGRPCProbesUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, }, // The following test steps of gRPC startup probe are expected to fail with startup probe check failures. // This is because, due to the unavailability of ready-to-use container images of a gRPC service that diff --git a/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go b/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go index 8df998cc8aab..1c5e7936000d 100644 --- a/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go +++ b/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go @@ -26,7 +26,7 @@ func TestAccContainerAttachedCluster_update(t *testing.T) { ResourceName: "google_container_attached_cluster.primary", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location"}, + ImportStateVerifyIgnore: []string{"location", "annotations"}, }, { Config: testAccContainerAttachedCluster_containerAttachedCluster_update(context), @@ -35,7 +35,7 @@ func TestAccContainerAttachedCluster_update(t *testing.T) { ResourceName: "google_container_attached_cluster.primary", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location"}, + ImportStateVerifyIgnore: []string{"location", "annotations"}, }, { Config: testAccContainerAttachedCluster_containerAttachedCluster_destroy(context), @@ -44,7 +44,7 @@ func TestAccContainerAttachedCluster_update(t *testing.T) { ResourceName: "google_container_attached_cluster.primary", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location"}, + ImportStateVerifyIgnore: []string{"location", "annotations"}, }, }, }) diff --git a/mmv1/third_party/terraform/tpgresource/annotations.go b/mmv1/third_party/terraform/tpgresource/annotations.go new file mode 100644 index 000000000000..f6a14211c8e8 --- /dev/null +++ b/mmv1/third_party/terraform/tpgresource/annotations.go @@ -0,0 +1,58 @@ +package tpgresource + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func SetAnnotationsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { + o, n := d.GetChange("annotations") + effectiveAnnotations := d.Get("effective_annotations").(map[string]interface{}) + + for k, v := range n.(map[string]interface{}) { + effectiveAnnotations[k] = v.(string) + } + + for k := range o.(map[string]interface{}) { + if _, ok := n.(map[string]interface{})[k]; !ok { + delete(effectiveAnnotations, k) + } + } + + if err := d.SetNew("effective_annotations", effectiveAnnotations); err != nil { + return fmt.Errorf("error setting new effective_annotations diff: %w", err) + } + + return nil +} + +func SetMetadataAnnotationsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { + l := d.Get("metadata").([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil + } + + o, n := d.GetChange("metadata.0.annotations") + effectiveAnnotations := d.Get("metadata.0.effective_annotations").(map[string]interface{}) + + for k, v := range n.(map[string]interface{}) { + effectiveAnnotations[k] = v.(string) + } + + for k := range o.(map[string]interface{}) { + if _, ok := n.(map[string]interface{})[k]; !ok { + delete(effectiveAnnotations, k) + } + } + + original := l[0].(map[string]interface{}) + original["effective_annotations"] = effectiveAnnotations + + if err := d.SetNew("metadata", []interface{}{original}); err != nil { + return fmt.Errorf("error setting new metadata diff: %w", err) + } + + return nil +} diff --git a/mmv1/third_party/terraform/tpgresource/labels.go b/mmv1/third_party/terraform/tpgresource/labels.go index e18d1323c890..06cb72c7c9bb 100644 --- a/mmv1/third_party/terraform/tpgresource/labels.go +++ b/mmv1/third_party/terraform/tpgresource/labels.go @@ -8,7 +8,7 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) -func SetTerraformLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { +func SetLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { config := meta.(*transport_tpg.Config) // Merge provider default labels with the user defined labels in the resource to get terraform managed labels @@ -26,12 +26,28 @@ func SetTerraformLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta inte return fmt.Errorf("error setting new terraform_labels diff: %w", err) } + o, n := d.GetChange("terraform_labels") + effectiveLabels := d.Get("effective_labels").(map[string]interface{}) + + for k, v := range n.(map[string]interface{}) { + effectiveLabels[k] = v.(string) + } + + for k := range o.(map[string]interface{}) { + if _, ok := n.(map[string]interface{})[k]; !ok { + delete(effectiveLabels, k) + } + } + + if err := d.SetNew("effective_labels", effectiveLabels); err != nil { + return fmt.Errorf("error setting new effective_labels diff: %w", err) + } + return nil } -func SetMetadataTerraformLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { - v := d.Get("metadata") - l := v.([]interface{}) +func SetMetadataLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { + l := d.Get("metadata").([]interface{}) if len(l) == 0 || l[0] == nil { return nil } @@ -49,10 +65,27 @@ func SetMetadataTerraformLabelsDiff(_ context.Context, d *schema.ResourceDiff, m terraformLabels[k] = v.(string) } - raw := l[0] - original := raw.(map[string]interface{}) + original := l[0].(map[string]interface{}) + original["terraform_labels"] = terraformLabels + if err := d.SetNew("metadata", []interface{}{original}); err != nil { + return fmt.Errorf("error setting new metadata diff: %w", err) + } + + o, n := d.GetChange("metadata.0.terraform_labels") + effectiveLabels := d.Get("metadata.0.effective_labels").(map[string]interface{}) + + for k, v := range n.(map[string]interface{}) { + effectiveLabels[k] = v.(string) + } + + for k := range o.(map[string]interface{}) { + if _, ok := n.(map[string]interface{})[k]; !ok { + delete(effectiveLabels, k) + } + } + original["effective_labels"] = effectiveLabels if err := d.SetNew("metadata", []interface{}{original}); err != nil { return fmt.Errorf("error setting new metadata diff: %w", err) } diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json index 1daf2ee28ffd..75f53ab54889 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset.tfplan.json @@ -18,6 +18,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -51,6 +54,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -65,6 +71,7 @@ "access": true, "creation_time": true, "default_encryption_configuration": [], + "effective_labels": {}, "etag": true, "id": true, "labels": {}, diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json index 7519ca4bd735..057733326a31 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_binding.tfplan.json @@ -17,6 +17,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -60,6 +63,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -75,6 +81,7 @@ "access": true, "creation_time": true, "default_encryption_configuration": [], + "effective_labels": {}, "etag": true, "id": true, "labels": {}, diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json index 6b0d5a89ce54..45223f402c7c 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_member.tfplan.json @@ -17,6 +17,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -60,6 +63,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -75,6 +81,7 @@ "access": true, "creation_time": true, "default_encryption_configuration": [], + "effective_labels": {}, "etag": true, "id": true, "labels": {}, diff --git a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json index 1725f40b59c3..7885b3b94ef0 100644 --- a/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_bigquery_dataset_iam_policy.tfplan.json @@ -17,6 +17,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -58,6 +61,9 @@ "default_table_expiration_ms": 3600000, "delete_contents_on_destroy": false, "description": null, + "effective_labels": { + "env": "dev" + }, "friendly_name": null, "labels": { "env": "dev" @@ -73,6 +79,7 @@ "access": true, "creation_time": true, "default_encryption_configuration": [], + "effective_labels": {}, "etag": true, "id": true, "labels": {}, From 1e2b51e482bb5fa85dfc7ff3c3f915f1d5cad565 Mon Sep 17 00:00:00 2001 From: abheda-crest <105624942+abheda-crest@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:58:08 +0530 Subject: [PATCH 028/476] Added support for `auto` and deprecated `automatic` field in `google_secret_manager_secret` resource (#8838) * Added support for automatic_replication field in google_secret_manager_secret resource * Replaced deprecated field automatic with automatic_replication in terraform configs * Improved the deprecation_message * Changed the name of field from automatic_replication to auto * Adjusted white spaces * Added test case to cover the automatic field --- mmv1/products/secretmanager/Secret.yaml | 39 +++- .../secret_manager_replication.go.erb | 180 +++++++++++++++ .../secret_manager_replication.go.erb | 118 ++++++++++ ...ervice_secret_environment_variables.tf.erb | 2 +- .../cloud_run_service_secret_volumes.tf.erb | 2 +- .../examples/cloudrunv2_job_secret.tf.erb | 2 +- .../examples/cloudrunv2_job_sql.tf.erb | 2 +- .../examples/cloudrunv2_service_secret.tf.erb | 2 +- .../examples/cloudrunv2_service_sql.tf.erb | 2 +- .../examples/dataform_repository.tf.erb | 2 +- .../dataform_repository_release_config.tf.erb | 2 +- ...dataform_repository_workflow_config.tf.erb | 2 +- ...rvices_edge_cache_keyset_dual_token.tf.erb | 2 +- ...k_services_edge_cache_origin_v4auth.tf.erb | 2 +- ...vices_edge_cache_service_dual_token.tf.erb | 2 +- .../examples/secret_version_basic.tf.erb | 2 +- .../examples/secret_with_annotations.tf.erb | 2 +- .../secret_with_automatic_cmek.tf.erb | 21 ++ .../resource_cloud_run_service_test.go.erb | 8 +- .../resource_dataform_repository_test.go.erb | 4 +- ...cret_manager_secret_version_access_test.go | 4 +- ...urce_secret_manager_secret_version_test.go | 4 +- ...resource_secret_manager_secret_test.go.erb | 206 +++++++++++++++++- ..._secret_manager_secret_version_test.go.erb | 4 +- .../samples/connection/ghe.tf.tmpl | 4 +- .../samples/connection/github.tf.tmpl | 2 +- .../samples/repository/ghe.tf.tmpl | 4 +- .../samples/repository/github.tf.tmpl | 2 +- 28 files changed, 592 insertions(+), 36 deletions(-) create mode 100644 mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb create mode 100644 mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb create mode 100644 mmv1/templates/terraform/examples/secret_with_automatic_cmek.tf.erb diff --git a/mmv1/products/secretmanager/Secret.yaml b/mmv1/products/secretmanager/Secret.yaml index 3f5c56174be8..c2e8a0832e77 100644 --- a/mmv1/products/secretmanager/Secret.yaml +++ b/mmv1/products/secretmanager/Secret.yaml @@ -38,6 +38,14 @@ examples: primary_resource_id: 'secret-with-annotations' vars: secret_id: 'secret' + - !ruby/object:Provider::Terraform::Examples + name: 'secret_with_automatic_cmek' + primary_resource_id: 'secret-with-automatic-cmek' + vars: + secret_id: 'secret' + kms_key_name: 'kms-key' + test_vars_overrides: + kms_key_name: 'acctest.BootstrapKMSKey(t).CryptoKey.Name' import_format: ['projects/{{project}}/secrets/{{secret_id}}'] custom_code: !ruby/object:Provider::Terraform::CustomCode pre_update: templates/terraform/pre_update/secret_manager_secret.go.erb @@ -109,6 +117,8 @@ properties: name: replication required: true immutable: true + custom_expand: templates/terraform/custom_expand/secret_manager_replication.go.erb + custom_flatten: templates/terraform/custom_flatten/secret_manager_replication.go.erb description: | The replication policy of the secret data attached to the Secret. It cannot be changed after the Secret has been created. @@ -119,16 +129,41 @@ properties: exactly_one_of: - replication.0.automatic - replication.0.user_managed + - replication.0.auto + deprecation_message: >- + `automatic` is deprecated and will be removed in a future major release. Use `auto` instead. + description: | + The Secret will automatically be replicated without any restrictions. + - !ruby/object:Api::Type::NestedObject + name: auto + api_name: automatic + immutable: true + exactly_one_of: + - replication.0.automatic + - replication.0.user_managed + - replication.0.auto description: | The Secret will automatically be replicated without any restrictions. - custom_flatten: templates/terraform/custom_flatten/object_to_bool.go.erb - custom_expand: templates/terraform/custom_expand/bool_to_object.go.erb + properties: + - !ruby/object:Api::Type::NestedObject + name: customerManagedEncryption + description: | + The customer-managed encryption configuration of the Secret. + If no configuration is provided, Google-managed default + encryption is used. + properties: + - !ruby/object:Api::Type::String + name: kmsKeyName + required: true + description: | + The resource name of the Cloud KMS CryptoKey used to encrypt secret payloads. - !ruby/object:Api::Type::NestedObject name: userManaged immutable: true exactly_one_of: - replication.0.automatic - replication.0.user_managed + - replication.0.auto description: | The Secret will be replicated to the regions specified by the user. properties: diff --git a/mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb b/mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb new file mode 100644 index 000000000000..af13a17e9002 --- /dev/null +++ b/mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb @@ -0,0 +1,180 @@ +<%# The license inside this block applies to this file. + # 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. +-%> +func expandSecretManagerSecretReplication(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{}) + + if _, ok := d.GetOk("replication.0.automatic"); ok{ + transformedAutomatic, err := expandSecretManagerSecretReplicationAutomatic(original["automatic"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAutomatic); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["automatic"] = transformedAutomatic + } + } + + if _, ok := d.GetOk("replication.0.auto"); ok{ + transformedAuto, err := expandSecretManagerSecretReplicationAuto(original["auto"], d, config) + if err != nil { + return nil, err + } else { + transformed["automatic"] = transformedAuto + } + } + + transformedUserManaged, err := expandSecretManagerSecretReplicationUserManaged(original["user_managed"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUserManaged); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["userManaged"] = transformedUserManaged + } + + return transformed, nil +} + +func expandSecretManagerSecretReplicationAutomatic(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + if v == nil || !v.(bool) { + return nil, nil + } + + return struct{}{}, nil +} + +func expandSecretManagerSecretReplicationAuto(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + + if l[0] == nil { + transformed := make(map[string]interface{}) + return transformed, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedCustomerManagedEncryption, err := expandSecretManagerSecretReplicationAutoCustomerManagedEncryption(original["customer_managed_encryption"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCustomerManagedEncryption); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["customerManagedEncryption"] = transformedCustomerManagedEncryption + } + + return transformed, nil +} + +func expandSecretManagerSecretReplicationAutoCustomerManagedEncryption(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{}) + + transformedKmsKeyName, err := expandSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(original["kms_key_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKmsKeyName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["kmsKeyName"] = transformedKmsKeyName + } + + return transformed, nil +} + +func expandSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecretManagerSecretReplicationUserManaged(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{}) + + transformedReplicas, err := expandSecretManagerSecretReplicationUserManagedReplicas(original["replicas"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedReplicas); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["replicas"] = transformedReplicas + } + + return transformed, nil +} + +func expandSecretManagerSecretReplicationUserManagedReplicas(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedLocation, err := expandSecretManagerSecretReplicationUserManagedReplicasLocation(original["location"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLocation); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["location"] = transformedLocation + } + + transformedCustomerManagedEncryption, err := expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(original["customer_managed_encryption"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCustomerManagedEncryption); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["customerManagedEncryption"] = transformedCustomerManagedEncryption + } + + req = append(req, transformed) + } + return req, nil +} + +func expandSecretManagerSecretReplicationUserManagedReplicasLocation(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(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{}) + + transformedKmsKeyName, err := expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(original["kms_key_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKmsKeyName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["kmsKeyName"] = transformedKmsKeyName + } + + return transformed, nil +} + +func expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb b/mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb new file mode 100644 index 000000000000..76f56f85396d --- /dev/null +++ b/mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb @@ -0,0 +1,118 @@ +<%# The license inside this block applies to this file. + # 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. +-%> +func flattenSecretManagerSecretReplication(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{}) + _, ok := d.GetOk("replication.0.automatic") + if ok { + transformed["automatic"] = + flattenSecretManagerSecretReplicationAutomatic(original["automatic"], d, config) + } else { + transformed["auto"] = + flattenSecretManagerSecretReplicationAuto(original["automatic"], d, config) + } + transformed["user_managed"] = + flattenSecretManagerSecretReplicationUserManaged(original["userManaged"], d, config) + return []interface{}{transformed} +} +func flattenSecretManagerSecretReplicationAutomatic(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v != nil +} + +func flattenSecretManagerSecretReplicationAuto(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + transformed := make(map[string]interface{}) + transformed["customer_managed_encryption"] = + flattenSecretManagerSecretReplicationAutoCustomerManagedEncryption(original["customerManagedEncryption"], d, config) + return []interface{}{transformed} +} +func flattenSecretManagerSecretReplicationAutoCustomerManagedEncryption(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["kms_key_name"] = + flattenSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(original["kmsKeyName"], d, config) + return []interface{}{transformed} +} +func flattenSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenSecretManagerSecretReplicationUserManaged(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["replicas"] = + flattenSecretManagerSecretReplicationUserManagedReplicas(original["replicas"], d, config) + return []interface{}{transformed} +} +func flattenSecretManagerSecretReplicationUserManagedReplicas(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "location": flattenSecretManagerSecretReplicationUserManagedReplicasLocation(original["location"], d, config), + "customer_managed_encryption": flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(original["customerManagedEncryption"], d, config), + }) + } + return transformed +} +func flattenSecretManagerSecretReplicationUserManagedReplicasLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(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["kms_key_name"] = + flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(original["kmsKeyName"], d, config) + return []interface{}{transformed} +} +func flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} diff --git a/mmv1/templates/terraform/examples/cloud_run_service_secret_environment_variables.tf.erb b/mmv1/templates/terraform/examples/cloud_run_service_secret_environment_variables.tf.erb index 42549eff36a7..da9c2e34b428 100644 --- a/mmv1/templates/terraform/examples/cloud_run_service_secret_environment_variables.tf.erb +++ b/mmv1/templates/terraform/examples/cloud_run_service_secret_environment_variables.tf.erb @@ -4,7 +4,7 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_id'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/cloud_run_service_secret_volumes.tf.erb b/mmv1/templates/terraform/examples/cloud_run_service_secret_volumes.tf.erb index 09936b296aae..a3ba0b82d169 100644 --- a/mmv1/templates/terraform/examples/cloud_run_service_secret_volumes.tf.erb +++ b/mmv1/templates/terraform/examples/cloud_run_service_secret_volumes.tf.erb @@ -4,7 +4,7 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_id'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/cloudrunv2_job_secret.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_job_secret.tf.erb index 917f870f4d11..387d0baf2b05 100644 --- a/mmv1/templates/terraform/examples/cloudrunv2_job_secret.tf.erb +++ b/mmv1/templates/terraform/examples/cloudrunv2_job_secret.tf.erb @@ -44,7 +44,7 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_id'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/cloudrunv2_job_sql.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_job_sql.tf.erb index 05d8ef7ce361..24740a509e58 100644 --- a/mmv1/templates/terraform/examples/cloudrunv2_job_sql.tf.erb +++ b/mmv1/templates/terraform/examples/cloudrunv2_job_sql.tf.erb @@ -48,7 +48,7 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_id'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/cloudrunv2_service_secret.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_service_secret.tf.erb index 802a55c1992c..5b06cd4ad619 100644 --- a/mmv1/templates/terraform/examples/cloudrunv2_service_secret.tf.erb +++ b/mmv1/templates/terraform/examples/cloudrunv2_service_secret.tf.erb @@ -32,7 +32,7 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_id'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/cloudrunv2_service_sql.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_service_sql.tf.erb index 9deecf6bd1aa..9a05e52a98f3 100644 --- a/mmv1/templates/terraform/examples/cloudrunv2_service_sql.tf.erb +++ b/mmv1/templates/terraform/examples/cloudrunv2_service_sql.tf.erb @@ -51,7 +51,7 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_id'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/dataform_repository.tf.erb b/mmv1/templates/terraform/examples/dataform_repository.tf.erb index 9db54244e401..7351b0625f26 100644 --- a/mmv1/templates/terraform/examples/dataform_repository.tf.erb +++ b/mmv1/templates/terraform/examples/dataform_repository.tf.erb @@ -8,7 +8,7 @@ resource "google_secret_manager_secret" "secret" { secret_id = "secret" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/dataform_repository_release_config.tf.erb b/mmv1/templates/terraform/examples/dataform_repository_release_config.tf.erb index 454d4dd3de93..e85ae9697814 100644 --- a/mmv1/templates/terraform/examples/dataform_repository_release_config.tf.erb +++ b/mmv1/templates/terraform/examples/dataform_repository_release_config.tf.erb @@ -8,7 +8,7 @@ resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_name'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/dataform_repository_workflow_config.tf.erb b/mmv1/templates/terraform/examples/dataform_repository_workflow_config.tf.erb index e4743c4f55dd..d8790a6af400 100644 --- a/mmv1/templates/terraform/examples/dataform_repository_workflow_config.tf.erb +++ b/mmv1/templates/terraform/examples/dataform_repository_workflow_config.tf.erb @@ -8,7 +8,7 @@ resource "google_secret_manager_secret" "secret" { secret_id = "<%= ctx[:vars]['secret_name'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/network_services_edge_cache_keyset_dual_token.tf.erb b/mmv1/templates/terraform/examples/network_services_edge_cache_keyset_dual_token.tf.erb index 1e6da83840d0..f3de7e77986b 100644 --- a/mmv1/templates/terraform/examples/network_services_edge_cache_keyset_dual_token.tf.erb +++ b/mmv1/templates/terraform/examples/network_services_edge_cache_keyset_dual_token.tf.erb @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "secret-basic" { secret_id = "<%= ctx[:vars]['secret_name'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/network_services_edge_cache_origin_v4auth.tf.erb b/mmv1/templates/terraform/examples/network_services_edge_cache_origin_v4auth.tf.erb index c9b4633cce96..3402b30dbed9 100644 --- a/mmv1/templates/terraform/examples/network_services_edge_cache_origin_v4auth.tf.erb +++ b/mmv1/templates/terraform/examples/network_services_edge_cache_origin_v4auth.tf.erb @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "secret-basic" { secret_id = "<%= ctx[:vars]['secret_name'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/network_services_edge_cache_service_dual_token.tf.erb b/mmv1/templates/terraform/examples/network_services_edge_cache_service_dual_token.tf.erb index d7df43d9cfef..b86f61c44e12 100644 --- a/mmv1/templates/terraform/examples/network_services_edge_cache_service_dual_token.tf.erb +++ b/mmv1/templates/terraform/examples/network_services_edge_cache_service_dual_token.tf.erb @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "secret-basic" { secret_id = "<%= ctx[:vars]['secret_name'] %>" replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/secret_version_basic.tf.erb b/mmv1/templates/terraform/examples/secret_version_basic.tf.erb index 3df2522be8f0..3bcaa96bd77c 100644 --- a/mmv1/templates/terraform/examples/secret_version_basic.tf.erb +++ b/mmv1/templates/terraform/examples/secret_version_basic.tf.erb @@ -6,7 +6,7 @@ resource "google_secret_manager_secret" "secret-basic" { } replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/secret_with_annotations.tf.erb b/mmv1/templates/terraform/examples/secret_with_annotations.tf.erb index 4ae910ae37e0..3199ce7781eb 100644 --- a/mmv1/templates/terraform/examples/secret_with_annotations.tf.erb +++ b/mmv1/templates/terraform/examples/secret_with_annotations.tf.erb @@ -14,6 +14,6 @@ resource "google_secret_manager_secret" "<%= ctx[:primary_resource_id] %>" { } replication { - automatic = true + auto {} } } diff --git a/mmv1/templates/terraform/examples/secret_with_automatic_cmek.tf.erb b/mmv1/templates/terraform/examples/secret_with_automatic_cmek.tf.erb new file mode 100644 index 000000000000..d268bcecaa08 --- /dev/null +++ b/mmv1/templates/terraform/examples/secret_with_automatic_cmek.tf.erb @@ -0,0 +1,21 @@ +data "google_project" "project" {} + +resource "google_kms_crypto_key_iam_member" "kms-secret-binding" { + crypto_key_id = "<%= ctx[:vars]['kms_key_name'] %>" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} + +resource "google_secret_manager_secret" "<%= ctx[:primary_resource_id] %>" { + secret_id = "<%= ctx[:vars]['secret_id'] %>" + + replication { + auto { + customer_managed_encryption { + kms_key_name = "<%= ctx[:vars]['kms_key_name'] %>" + } + } + } + + depends_on = [ google_kms_crypto_key_iam_member.kms-secret-binding ] +} diff --git a/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb b/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb index 0556789b6735..a0f84d5ebb97 100644 --- a/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb +++ b/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb @@ -184,14 +184,14 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret1" { secret_id = "%s" replication { - automatic = true + auto {} } } resource "google_secret_manager_secret" "secret2" { secret_id = "%s" replication { - automatic = true + auto {} } } @@ -308,14 +308,14 @@ data "google_project" "project" { resource "google_secret_manager_secret" "secret1" { secret_id = "%s" replication { - automatic = true + auto {} } } resource "google_secret_manager_secret" "secret2" { secret_id = "%s" replication { - automatic = true + auto {} } } diff --git a/mmv1/third_party/terraform/services/dataform/resource_dataform_repository_test.go.erb b/mmv1/third_party/terraform/services/dataform/resource_dataform_repository_test.go.erb index 79043dd0fea3..fd24afe43b3f 100644 --- a/mmv1/third_party/terraform/services/dataform/resource_dataform_repository_test.go.erb +++ b/mmv1/third_party/terraform/services/dataform/resource_dataform_repository_test.go.erb @@ -56,7 +56,7 @@ resource "google_secret_manager_secret" "secret" { secret_id = "secret" replication { - automatic = true + auto {} } } @@ -98,7 +98,7 @@ resource "google_secret_manager_secret" "secret" { secret_id = "secret" replication { - automatic = true + auto {} } } diff --git a/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_access_test.go b/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_access_test.go index 68dbc8b2bba5..5cce384fb01f 100644 --- a/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_access_test.go +++ b/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_access_test.go @@ -82,7 +82,7 @@ resource "google_secret_manager_secret" "secret-basic" { label = "my-label" } replication { - automatic = true + auto {} } } @@ -112,7 +112,7 @@ resource "google_secret_manager_secret" "secret-basic" { label = "my-label" } replication { - automatic = true + auto {} } } diff --git a/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_test.go b/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_test.go index a63c713c05dd..835e0b2e37a0 100644 --- a/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_test.go +++ b/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret_version_test.go @@ -82,7 +82,7 @@ resource "google_secret_manager_secret" "secret-basic" { label = "my-label" } replication { - automatic = true + auto {} } } @@ -112,7 +112,7 @@ resource "google_secret_manager_secret" "secret-basic" { label = "my-label" } replication { - automatic = true + auto {} } } diff --git a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb index 347d5e842a40..e5c61c864c25 100644 --- a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb +++ b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb @@ -217,6 +217,72 @@ func TestAccSecretManagerSecret_userManagedCmekUpdate(t *testing.T) { }) } +func TestAccSecretManagerSecret_automaticCmekUpdate(t *testing.T) { + t.Parallel() + + suffix := acctest.RandString(t, 10) + key1 := acctest.BootstrapKMSKeyWithPurposeInLocationAndName(t, "ENCRYPT_DECRYPT", "global", "tf-secret-manager-automatic-key1") + key2 := acctest.BootstrapKMSKeyWithPurposeInLocationAndName(t, "ENCRYPT_DECRYPT", "global", "tf-secret-manager-automatic-key2") + context := map[string]interface{}{ + "pid": envvar.GetTestProjectFromEnv(), + "random_suffix": suffix, + "kms_key_name_1": key1.CryptoKey.Name, + "kms_key_name_2": key2.CryptoKey.Name, + } + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckSecretManagerSecretDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccSecretMangerSecret_automaticBasic(context), + }, + { + ResourceName: "google_secret_manager_secret.secret-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ttl", "replication.0.automatic", "replication.0.auto"}, + }, + { + Config: testAccSecretMangerSecret_automaticCmekBasic(context), + }, + { + ResourceName: "google_secret_manager_secret.secret-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ttl"}, + }, + { + Config: testAccSecretMangerSecret_automaticCmekUpdate(context), + }, + { + ResourceName: "google_secret_manager_secret.secret-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ttl"}, + }, + { + Config: testAccSecretMangerSecret_automaticCmekUpdate2(context), + }, + { + ResourceName: "google_secret_manager_secret.secret-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ttl"}, + }, + { + Config: testAccSecretMangerSecret_automaticCmekBasic(context), + }, + { + ResourceName: "google_secret_manager_secret.secret-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ttl"}, + }, + }, + }) +} + func testAccSecretManagerSecret_basic(context map[string]interface{}) string { return acctest.Nprintf(` resource "google_secret_manager_secret" "secret-basic" { @@ -299,7 +365,7 @@ resource "google_secret_manager_secret" "secret-with-annotations" { } replication { - automatic = true + auto {} } } `, context) @@ -322,7 +388,7 @@ resource "google_secret_manager_secret" "secret-with-annotations" { } replication { - automatic = true + auto {} } } `, context) @@ -631,3 +697,139 @@ resource "google_secret_manager_secret" "secret-basic" { } `, context) } + +func testAccSecretMangerSecret_automaticBasic(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { + project_id = "%{pid}" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-1" { + crypto_key_id = "%{kms_key_name_1}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-2" { + crypto_key_id = "%{kms_key_name_2}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "tf-test-secret-%{random_suffix}" + + labels = { + label = "my-label" + } + replication { + automatic = true + } + depends_on = [ + google_kms_crypto_key_iam_member.kms-secret-binding-1, + google_kms_crypto_key_iam_member.kms-secret-binding-2, + ] +} +`, context) +} + +func testAccSecretMangerSecret_automaticCmekBasic(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { + project_id = "%{pid}" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-1" { + crypto_key_id = "%{kms_key_name_1}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-2" { + crypto_key_id = "%{kms_key_name_2}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "tf-test-secret-%{random_suffix}" + + labels = { + label = "my-label" + } + replication { + auto {} + } + depends_on = [ + google_kms_crypto_key_iam_member.kms-secret-binding-1, + google_kms_crypto_key_iam_member.kms-secret-binding-2, + ] +} +`, context) +} + +func testAccSecretMangerSecret_automaticCmekUpdate(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { + project_id = "%{pid}" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-1" { + crypto_key_id = "%{kms_key_name_1}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-2" { + crypto_key_id = "%{kms_key_name_2}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "tf-test-secret-%{random_suffix}" + + labels = { + label = "my-label" + } + replication { + auto { + customer_managed_encryption { + kms_key_name = "%{kms_key_name_1}" + } + } + } + depends_on = [ + google_kms_crypto_key_iam_member.kms-secret-binding-1, + google_kms_crypto_key_iam_member.kms-secret-binding-2, + ] +} +`, context) +} + +func testAccSecretMangerSecret_automaticCmekUpdate2(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { + project_id = "%{pid}" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-1" { + crypto_key_id = "%{kms_key_name_1}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_kms_crypto_key_iam_member" "kms-secret-binding-2" { + crypto_key_id = "%{kms_key_name_2}" + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" +} +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "tf-test-secret-%{random_suffix}" + + labels = { + label = "my-label" + } + replication { + auto { + customer_managed_encryption { + kms_key_name = "%{kms_key_name_2}" + } + } + } + depends_on = [ + google_kms_crypto_key_iam_member.kms-secret-binding-1, + google_kms_crypto_key_iam_member.kms-secret-binding-2, + ] +} +`, context) +} diff --git a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_version_test.go.erb b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_version_test.go.erb index a32799872899..375e6b73b12f 100644 --- a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_version_test.go.erb +++ b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_version_test.go.erb @@ -61,7 +61,7 @@ resource "google_secret_manager_secret" "secret-basic" { } replication { - automatic = true + auto {} } } @@ -84,7 +84,7 @@ resource "google_secret_manager_secret" "secret-basic" { } replication { - automatic = true + auto {} } } diff --git a/tpgtools/overrides/cloudbuildv2/samples/connection/ghe.tf.tmpl b/tpgtools/overrides/cloudbuildv2/samples/connection/ghe.tf.tmpl index 2aece6005734..6841ab373a64 100644 --- a/tpgtools/overrides/cloudbuildv2/samples/connection/ghe.tf.tmpl +++ b/tpgtools/overrides/cloudbuildv2/samples/connection/ghe.tf.tmpl @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "private-key-secret" { secret_id = "ghe-pk-secret" replication { - automatic = true + auto {} } } @@ -15,7 +15,7 @@ resource "google_secret_manager_secret" "webhook-secret-secret" { secret_id = "github-token-secret" replication { - automatic = true + auto {} } } diff --git a/tpgtools/overrides/cloudbuildv2/samples/connection/github.tf.tmpl b/tpgtools/overrides/cloudbuildv2/samples/connection/github.tf.tmpl index f25048ef1443..05bd5d6b81dc 100644 --- a/tpgtools/overrides/cloudbuildv2/samples/connection/github.tf.tmpl +++ b/tpgtools/overrides/cloudbuildv2/samples/connection/github.tf.tmpl @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "github-token-secret" { secret_id = "github-token-secret" replication { - automatic = true + auto {} } } diff --git a/tpgtools/overrides/cloudbuildv2/samples/repository/ghe.tf.tmpl b/tpgtools/overrides/cloudbuildv2/samples/repository/ghe.tf.tmpl index 3f6ec4778b26..bf307ddefa98 100644 --- a/tpgtools/overrides/cloudbuildv2/samples/repository/ghe.tf.tmpl +++ b/tpgtools/overrides/cloudbuildv2/samples/repository/ghe.tf.tmpl @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "private-key-secret" { secret_id = "ghe-pk-secret" replication { - automatic = true + auto {} } } @@ -15,7 +15,7 @@ resource "google_secret_manager_secret" "webhook-secret-secret" { secret_id = "github-token-secret" replication { - automatic = true + auto {} } } diff --git a/tpgtools/overrides/cloudbuildv2/samples/repository/github.tf.tmpl b/tpgtools/overrides/cloudbuildv2/samples/repository/github.tf.tmpl index 3058a12649d1..1f9f311c850c 100644 --- a/tpgtools/overrides/cloudbuildv2/samples/repository/github.tf.tmpl +++ b/tpgtools/overrides/cloudbuildv2/samples/repository/github.tf.tmpl @@ -2,7 +2,7 @@ resource "google_secret_manager_secret" "github-token-secret" { secret_id = "github-token-secret" replication { - automatic = true + auto {} } } From 33e2ef5365d58eafeb417a1c726cdd167e338371 Mon Sep 17 00:00:00 2001 From: pengq-google Date: Mon, 11 Sep 2023 11:50:47 -0400 Subject: [PATCH 029/476] Add google_logging_metric to version 5 upgrade doc for #8780 (#8887) Co-authored-by: Cameron Thornton --- .../docs/guides/version_5_upgrade.html.markdown | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown index f1aed2ca0784..0e5eaa65dde4 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown @@ -385,6 +385,18 @@ If you were relying on accessing an individual flag by index (for example, `goog Previously, the default value for `rule.rate_limit_options.encorce_on_key` is "ALL", now this field no longer has a default value. +## Resource: `google_logging_metric` + +### Additional `bucket_options` subfields are now properly required + +When setting the `bucket_options` block, the following fields may be required: + +* `num_finite_buckets`, `width`, and `offset` are now required when `bucket_options.linear_buckets` is set. + +* `num_finite_buckets`, `growth_factor`, and `scale` are now required when `bucket_options.exponential_buckets` is set. + +Previously these fields should have been required but were not, which allowed for invalid `google_logging_metric` configurations. + ## Resource: `google_logging_project_sink` ### `unique_writer_identity` now defaults to `TRUE` @@ -437,4 +449,4 @@ resource "google_project_iam_binding" "gcs-bucket-writer" { ### `Create` endpoint is used to create the resource -`google_service_networking_connection` now uses the Create endpoint instead of the Patch endpoint during the creation step. Previously, Patch was used as a workaround for an issue that has since been resolved. \ No newline at end of file +`google_service_networking_connection` now uses the Create endpoint instead of the Patch endpoint during the creation step. Previously, Patch was used as a workaround for an issue that has since been resolved. From b3d099eb0b4c762f0d81448c0fdedd20f0ec8089 Mon Sep 17 00:00:00 2001 From: "Bob \"Wombat\" Hogg" Date: Mon, 11 Sep 2023 12:03:41 -0400 Subject: [PATCH 030/476] Add point_in_time_recovery_enablement and corresponding output fields to firestore_database (#8863) --- mmv1/products/firestore/Database.yaml | 27 +++++++ .../examples/firestore_database.tf.erb | 13 ++-- ...irestore_database_in_datastore_mode.tf.erb | 14 ++-- ...urce_firestore_database_update_test.go.erb | 75 +++++++++++++++++-- 4 files changed, 108 insertions(+), 21 deletions(-) diff --git a/mmv1/products/firestore/Database.yaml b/mmv1/products/firestore/Database.yaml index 5fa7e8ba5290..70c6bb4b1200 100644 --- a/mmv1/products/firestore/Database.yaml +++ b/mmv1/products/firestore/Database.yaml @@ -147,6 +147,18 @@ properties: - :ENABLED - :DISABLED default_from_api: true + - !ruby/object:Api::Type::Enum + name: pointInTimeRecoveryEnablement + description: | + Whether to enable the PITR feature on this database. + If `POINT_IN_TIME_RECOVERY_ENABLED` is selected, reads are supported on selected versions of the data from within the past 7 days. + versionRetentionPeriod and earliestVersionTime can be used to determine the supported versions. These include reads against any timestamp within the past hour + and reads against 1-minute snapshots beyond 1 hour and within 7 days. + If `POINT_IN_TIME_RECOVERY_DISABLED` is selected, reads are supported on any version of the data from within the past 1 hour. + values: + - :POINT_IN_TIME_RECOVERY_ENABLED + - :POINT_IN_TIME_RECOVERY_DISABLED + default_value: :POINT_IN_TIME_RECOVERY_DISABLED - !ruby/object:Api::Type::String name: key_prefix description: | @@ -167,3 +179,18 @@ properties: description: | The timestamp at which this database was created. output: true + - !ruby/object:Api::Type::String + name: versionRetentionPeriod + description: | + Output only. The period during which past versions of data are retained in the database. + Any read or query can specify a readTime within this window, and will read the state of the database at that time. + If the PITR feature is enabled, the retention period is 7 days. Otherwise, the retention period is 1 hour. + A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s". + output: true + - !ruby/object:Api::Type::String + name: earliestVersionTime + description: | + Output only. The earliest timestamp at which older versions of the data can be read from the database. See versionRetentionPeriod above; this field is populated with now - versionRetentionPeriod. + This value is continuously updated, and becomes stale the moment it is queried. If you are using this value to recover data, make sure to account for the time from the moment when the value is queried to the moment when you initiate the recovery. + 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". + output: true diff --git a/mmv1/templates/terraform/examples/firestore_database.tf.erb b/mmv1/templates/terraform/examples/firestore_database.tf.erb index 659e57bbf1fa..c5e4c042ff95 100644 --- a/mmv1/templates/terraform/examples/firestore_database.tf.erb +++ b/mmv1/templates/terraform/examples/firestore_database.tf.erb @@ -20,12 +20,13 @@ resource "google_project_service" "firestore" { } resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" { - project = google_project.project.project_id - name = "my-database" - location_id = "nam5" - type = "FIRESTORE_NATIVE" - concurrency_mode = "OPTIMISTIC" - app_engine_integration_mode = "DISABLED" + project = google_project.project.project_id + name = "my-database" + location_id = "nam5" + type = "FIRESTORE_NATIVE" + concurrency_mode = "OPTIMISTIC" + app_engine_integration_mode = "DISABLED" + point_in_time_recovery_enablement = "POINT_IN_TIME_RECOVERY_ENABLED" depends_on = [google_project_service.firestore] } diff --git a/mmv1/templates/terraform/examples/firestore_database_in_datastore_mode.tf.erb b/mmv1/templates/terraform/examples/firestore_database_in_datastore_mode.tf.erb index 1f3b00af89b9..f4764e9386ed 100644 --- a/mmv1/templates/terraform/examples/firestore_database_in_datastore_mode.tf.erb +++ b/mmv1/templates/terraform/examples/firestore_database_in_datastore_mode.tf.erb @@ -19,13 +19,13 @@ resource "google_project_service" "firestore" { } resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" { - project = google_project.project.project_id - name = "datastore-mode-database" - location_id = "nam5" - type = "DATASTORE_MODE" - concurrency_mode = "OPTIMISTIC" - app_engine_integration_mode = "DISABLED" + project = google_project.project.project_id + name = "datastore-mode-database" + location_id = "nam5" + type = "DATASTORE_MODE" + concurrency_mode = "OPTIMISTIC" + app_engine_integration_mode = "DISABLED" + point_in_time_recovery_enablement = "POINT_IN_TIME_RECOVERY_ENABLED" depends_on = [google_project_service.firestore] } - diff --git a/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb b/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb index 66ef2cf86766..abdc7c69803b 100644 --- a/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb +++ b/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb @@ -10,10 +10,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccFirestoreDatabase_update(t *testing.T) { +func TestAccFirestoreDatabase_updateConcurrencyMode(t *testing.T) { t.Parallel() orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) randomSuffix := acctest.RandString(t, 10) acctest.VcrTest(t, resource.TestCase{ @@ -24,7 +25,7 @@ func TestAccFirestoreDatabase_update(t *testing.T) { }, Steps: []resource.TestStep{ { - Config: testAccFirestoreDatabase_concurrencyMode(orgId, randomSuffix, "OPTIMISTIC"), + Config: testAccFirestoreDatabase_concurrencyMode(orgId, billingAccount, randomSuffix, "OPTIMISTIC"), }, { ResourceName: "google_firestore_database.default", @@ -33,7 +34,7 @@ func TestAccFirestoreDatabase_update(t *testing.T) { ImportStateVerifyIgnore: []string{"etag", "project"}, }, { - Config: testAccFirestoreDatabase_concurrencyMode(orgId, randomSuffix, "PESSIMISTIC"), + Config: testAccFirestoreDatabase_concurrencyMode(orgId, billingAccount, randomSuffix, "PESSIMISTIC"), }, { ResourceName: "google_firestore_database.default", @@ -45,12 +46,49 @@ func TestAccFirestoreDatabase_update(t *testing.T) { }) } -func testAccFirestoreDatabase_concurrencyMode(orgId string, randomSuffix string, concurrencyMode string) string { +func TestAccFirestoreDatabase_updatePitrEnablement(t *testing.T) { + t.Parallel() + + orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) + randomSuffix := 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: testAccFirestoreDatabase_pitrEnablement(orgId, billingAccount, randomSuffix, "POINT_IN_TIME_RECOVERY_ENABLED"), + }, + { + ResourceName: "google_firestore_database.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"etag", "project"}, + }, + { + Config: testAccFirestoreDatabase_pitrEnablement(orgId, billingAccount, randomSuffix, "POINT_IN_TIME_RECOVERY_DISABLED"), + }, + { + ResourceName: "google_firestore_database.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"etag", "project"}, + }, + }, + }) +} + +func testAccFirestoreDatabase_basicDependencies(orgId, billingAccount string, randomSuffix string) string { return fmt.Sprintf(` resource "google_project" "default" { - project_id = "tf-test%s" - name = "tf-test%s" - org_id = "%s" + project_id = "tf-test%s" + name = "tf-test%s" + org_id = "%s" + billing_account = "%s" } resource "time_sleep" "wait_60_seconds" { @@ -66,6 +104,11 @@ resource "google_project_service" "firestore" { # Needed for CI tests for permissions to propagate, should not be needed for actual usage depends_on = [time_sleep.wait_60_seconds] } +`, randomSuffix, randomSuffix, orgId, billingAccount) +} + +func testAccFirestoreDatabase_concurrencyMode(orgId, billingAccount string, randomSuffix string, concurrencyMode string) string { + return testAccFirestoreDatabase_basicDependencies(orgId, billingAccount, randomSuffix) + fmt.Sprintf(` resource "google_firestore_database" "default" { name = "(default)" @@ -77,5 +120,21 @@ resource "google_firestore_database" "default" { depends_on = [google_project_service.firestore] } -`, randomSuffix, randomSuffix, orgId, concurrencyMode) +`, concurrencyMode) +} + +func testAccFirestoreDatabase_pitrEnablement(orgId, billingAccount string, randomSuffix string, pointInTimeRecoveryEnablement string) string { + return testAccFirestoreDatabase_basicDependencies(orgId, billingAccount, randomSuffix) + fmt.Sprintf(` + +resource "google_firestore_database" "default" { + name = "(default)" + type = "DATASTORE_MODE" + location_id = "nam5" + point_in_time_recovery_enablement = "%s" + + project = google_project.default.project_id + + depends_on = [google_project_service.firestore] +} +`, pointInTimeRecoveryEnablement) } From 75597f462ca1e4201080ea6d8825935a776c8d3f Mon Sep 17 00:00:00 2001 From: Nick Elliot Date: Mon, 11 Sep 2023 10:12:41 -0700 Subject: [PATCH 031/476] V5 upgrade docs updated for Default Provider Values and Data Source 404 erroring (#8903) --- .../website/docs/guides/version_5_upgrade.html.markdown | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown index 0e5eaa65dde4..88ec1304641f 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown @@ -118,8 +118,16 @@ The new annotations model is similar to the new labels model and will be applied There are now two annotation-related fields with the new model, the `annotations` and the output-only `effective_annotations` fields. +### Provider default values shown at plan-time + +`project`, `region`, and `zone` fields will now display their values during plan-time instead of the placeholder `(known after apply)` value normally displayed for fields without fixed Terraform default values. These values will be taken from either the Terraform resource config file, provider config, or local environment variables, depending on which variables are supplied by the user, matching the existing per-resource functionality for what default values are used in execution of a Terraform plan. + ## Datasources +### Datasources now error universally on 404 + +All data sources have been updated to return an error when a target resource URI can not be reached. Previously this was inconsistent between different datasources in whether an empty value was returned to Terraform state upon 404 or if an error was returned, but this has been standardized. Any plans that reference datasources which no longer exist (or do not exist yet) will need to be revised to have these datasources removed from configuration files. + ## Datasource: `google_product_datasource` ### Datasource-level change example header From df9725a7dfeffdced3a5ca1c3ddd35101abc4bf4 Mon Sep 17 00:00:00 2001 From: Nick Elliot Date: Mon, 11 Sep 2023 10:13:02 -0700 Subject: [PATCH 032/476] existing Data Sources now return errors on 404s (#8858) --- ...e_access_approval_folder_service_account.go | 2 +- ...ss_approval_organization_service_account.go | 2 +- ..._access_approval_project_service_account.go | 2 +- .../alloydb/data_source_alloydb_locations.go | 4 ++-- ..._source_alloydb_supported_database_flags.go | 4 ++-- ...oogle_app_engine_default_service_account.go | 2 +- ...data_source_artifact_registry_repository.go | 7 ++++++- ..._source_google_beyondcorp_app_connection.go | 14 ++++++++++++-- ...a_source_google_beyondcorp_app_connector.go | 14 ++++++++++++-- ...ata_source_google_beyondcorp_app_gateway.go | 14 ++++++++++++-- ..._google_bigquery_default_service_account.go | 2 +- .../data_source_google_billing_account.go | 2 +- .../data_source_google_cloudbuild_trigger.go | 13 +++++++++++-- ...ta_source_google_cloudfunctions_function.go | 6 ++++++ ...a_source_google_cloudfunctions2_function.go | 7 ++++++- ...rce_cloud_identity_group_memberships.go.erb | 2 +- .../data_source_cloud_identity_groups.go.erb | 2 +- .../cloudrun/data_source_cloud_run_service.go | 11 ++++++++++- .../data_source_google_composer_environment.go | 13 +++++++++++-- .../data_source_compute_health_check.go | 13 ++++++++++++- ...ta_source_compute_network_endpoint_group.go | 18 +++++++++++++++--- .../data_source_compute_network_peering.go | 14 ++++++++++++-- .../data_source_google_compute_address.go | 6 ++++-- ...ata_source_google_compute_backend_bucket.go | 14 ++++++++++++-- ...ta_source_google_compute_backend_service.go | 14 ++++++++++++-- ...e_google_compute_default_service_account.go | 4 ++-- .../compute/data_source_google_compute_disk.go | 11 ++++++++++- ...ta_source_google_compute_forwarding_rule.go | 14 ++++++++++++-- ...ata_source_google_compute_global_address.go | 6 ++++-- ...ata_source_google_compute_ha_vpn_gateway.go | 14 ++++++++++++-- .../data_source_google_compute_instance.go.erb | 4 +++- ...ata_source_google_compute_instance_group.go | 17 ++++++++++++++--- .../data_source_google_compute_network.go | 7 +++++-- ...google_compute_region_instance_group.go.erb | 6 +++--- ...le_compute_region_network_endpoint_group.go | 16 +++++++++++++--- ...ce_google_compute_region_ssl_certificate.go | 13 +++++++++++-- ...ource_google_compute_resource_policy.go.erb | 14 ++++++++++++-- .../data_source_google_compute_router.go | 12 +++++++++++- .../data_source_google_compute_router_nat.go | 11 ++++++++++- ...ta_source_google_compute_ssl_certificate.go | 14 ++++++++++++-- .../data_source_google_compute_ssl_policy.go | 14 ++++++++++++-- ...ata_source_google_compute_subnetwork.go.erb | 5 +++-- ...ta_source_google_compute_vpn_gateway.go.erb | 5 +++-- ...ce_google_global_compute_forwarding_rule.go | 14 ++++++++++++-- ...ta_source_dataproc_metastore_service.go.erb | 10 +++++++++- .../services/dns/data_source_dns_keys.go | 5 +---- ...a_source_google_firebase_android_app.go.erb | 10 +++++++++- ...ata_source_google_firebase_apple_app.go.erb | 10 +++++++++- .../data_source_google_firebase_web_app.go.erb | 10 +++++++++- ...urce_google_firebase_hosting_channel.go.erb | 10 +++++++++- ...urce_iam_beta_workload_identity_pool.go.erb | 10 +++++++++- ...beta_workload_identity_pool_provider.go.erb | 10 +++++++++- .../services/iap/data_source_iap_client.go | 10 +++++++++- .../kms/data_source_google_kms_crypto_key.go | 15 +++++++++++++-- ...ata_source_google_kms_crypto_key_version.go | 4 ++-- .../kms/data_source_google_kms_key_ring.go | 15 +++++++++++++-- ...rce_google_logging_project_cmek_settings.go | 2 +- .../logging/data_source_google_logging_sink.go | 2 +- .../data_source_certificate_authority.go | 2 +- .../pubsub/data_source_pubsub_subscription.go | 10 +++++++++- .../pubsub/data_source_pubsub_topic.go | 10 +++++++++- .../redis/data_source_redis_instance.go | 12 +++++++++++- .../data_source_google_folder.go | 5 +++-- ...source_google_folder_organization_policy.go | 13 +++++++++++-- .../data_source_google_iam_role.go | 2 +- .../data_source_google_organization.go | 2 +- ...ource_google_project_organization_policy.go | 13 +++++++++++-- .../data_source_google_project_service.go | 10 +++++++++- .../data_source_google_service_account.go | 2 +- .../data_source_google_service_account_key.go | 2 +- .../data_source_runtimeconfig_config.go.erb | 10 +++++++++- .../data_source_runtimeconfig_variable.go.erb | 10 +++++++++- .../data_source_secret_manager_secret.go | 10 +++++++++- .../data_source_sourcerepo_repository.go | 10 +++++++++- .../spanner/data_source_spanner_instance.go | 10 +++++++++- .../services/sql/data_source_sql_database.go | 6 +++++- .../sql/data_source_sql_database_instance.go | 12 +++++++++++- .../services/sql/data_source_sql_databases.go | 2 +- ...e_google_storage_project_service_account.go | 2 +- ...storage_transfer_project_service_account.go | 2 +- .../vertexai/data_source_vertex_ai_index.go | 10 +++++++++- ...a_source_google_vmwareengine_cluster.go.erb | 10 +++++++++- ...a_source_google_vmwareengine_network.go.erb | 10 +++++++++- ...ce_google_vmwareengine_private_cloud.go.erb | 10 +++++++++- .../data_source_vpc_access_connector.go | 10 +++++++++- .../terraform/transport/transport.go | 9 +++++++++ 86 files changed, 618 insertions(+), 124 deletions(-) diff --git a/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_folder_service_account.go b/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_folder_service_account.go index 2bc48454a986..4727870ba944 100644 --- a/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_folder_service_account.go +++ b/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_folder_service_account.go @@ -56,7 +56,7 @@ func dataSourceAccessApprovalFolderServiceAccountRead(d *schema.ResourceData, me UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("AccessApprovalFolderServiceAccount %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("AccessApprovalFolderServiceAccount %q", d.Id()), url) } if err := d.Set("name", res["name"]); err != nil { diff --git a/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_organization_service_account.go b/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_organization_service_account.go index b7b2005fbc6e..d785f52f82ed 100644 --- a/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_organization_service_account.go +++ b/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_organization_service_account.go @@ -56,7 +56,7 @@ func dataSourceAccessApprovalOrganizationServiceAccountRead(d *schema.ResourceDa UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("AccessApprovalOrganizationServiceAccount %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("AccessApprovalOrganizationServiceAccount %q", d.Id()), url) } if err := d.Set("name", res["name"]); err != nil { diff --git a/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_project_service_account.go b/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_project_service_account.go index 1f9794f50e5e..4a0cf4b73036 100644 --- a/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_project_service_account.go +++ b/mmv1/third_party/terraform/services/accessapproval/data_source_access_approval_project_service_account.go @@ -56,7 +56,7 @@ func dataSourceAccessApprovalProjectServiceAccountRead(d *schema.ResourceData, m UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("AccessApprovalProjectServiceAccount %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("AccessApprovalProjectServiceAccount %q", d.Id()), url) } if err := d.Set("name", res["name"]); err != nil { diff --git a/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_locations.go b/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_locations.go index d23793f6a7d2..e79df23ac67b 100644 --- a/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_locations.go +++ b/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_locations.go @@ -94,7 +94,7 @@ func dataSourceAlloydbLocationsRead(d *schema.ResourceData, meta interface{}) er UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Locations %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Locations %q", d.Id()), url) } var locations []map[string]interface{} for { @@ -142,7 +142,7 @@ func dataSourceAlloydbLocationsRead(d *schema.ResourceData, meta interface{}) er UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Locations %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Locations %q", d.Id()), url) } } diff --git a/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_supported_database_flags.go b/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_supported_database_flags.go index 6404eaa63247..a1615661d5cc 100644 --- a/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_supported_database_flags.go +++ b/mmv1/third_party/terraform/services/alloydb/data_source_alloydb_supported_database_flags.go @@ -147,7 +147,7 @@ func dataSourceAlloydbSupportedDatabaseFlagsRead(d *schema.ResourceData, meta in UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("SupportedDatabaseFlags %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("SupportedDatabaseFlags %q", d.Id()), url) } var supportedDatabaseFlags []map[string]interface{} for { @@ -221,7 +221,7 @@ func dataSourceAlloydbSupportedDatabaseFlagsRead(d *schema.ResourceData, meta in UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("SupportedDatabaseFlags %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("SupportedDatabaseFlags %q", d.Id()), url) } } if err := d.Set("supported_database_flags", supportedDatabaseFlags); err != nil { diff --git a/mmv1/third_party/terraform/services/appengine/data_source_google_app_engine_default_service_account.go b/mmv1/third_party/terraform/services/appengine/data_source_google_app_engine_default_service_account.go index bd38291084d5..99764bfe0fcf 100644 --- a/mmv1/third_party/terraform/services/appengine/data_source_google_app_engine_default_service_account.go +++ b/mmv1/third_party/terraform/services/appengine/data_source_google_app_engine_default_service_account.go @@ -62,7 +62,7 @@ func dataSourceGoogleAppEngineDefaultServiceAccountRead(d *schema.ResourceData, sa, err := config.NewIamClient(userAgent).Projects.ServiceAccounts.Get(serviceAccountName).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Service Account %q", serviceAccountName)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Service Account %q", serviceAccountName), serviceAccountName) } d.SetId(sa.Name) diff --git a/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository.go b/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository.go index 09c832b4aff9..fb0271a17040 100644 --- a/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository.go +++ b/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository.go @@ -38,12 +38,17 @@ func dataSourceArtifactRegistryRepositoryRead(d *schema.ResourceData, meta inter } repository_id := d.Get("repository_id").(string) - d.SetId(fmt.Sprintf("projects/%s/locations/%s/repositories/%s", project, location, repository_id)) + id := fmt.Sprintf("projects/%s/locations/%s/repositories/%s", project, location, repository_id) + d.SetId(id) err = resourceArtifactRegistryRepositoryRead(d, meta) if err != nil { return err } + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connection.go b/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connection.go index fef0cf119493..13d16ca2c5de 100644 --- a/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connection.go +++ b/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connection.go @@ -38,7 +38,17 @@ func dataSourceGoogleBeyondcorpAppConnectionRead(d *schema.ResourceData, meta in return err } - d.SetId(fmt.Sprintf("projects/%s/locations/%s/appConnections/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/locations/%s/appConnections/%s", project, region, name) + d.SetId(id) - return resourceBeyondcorpAppConnectionRead(d, meta) + err = resourceBeyondcorpAppConnectionRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connector.go b/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connector.go index 202941b1448c..b06bc5f4fbbe 100644 --- a/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connector.go +++ b/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_connector.go @@ -38,7 +38,17 @@ func dataSourceGoogleBeyondcorpAppConnectorRead(d *schema.ResourceData, meta int return err } - d.SetId(fmt.Sprintf("projects/%s/locations/%s/appConnectors/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/locations/%s/appConnectors/%s", project, region, name) + d.SetId(id) - return resourceBeyondcorpAppConnectorRead(d, meta) + err = resourceBeyondcorpAppConnectorRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_gateway.go b/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_gateway.go index a713c74e6a25..104f2798482e 100644 --- a/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_gateway.go +++ b/mmv1/third_party/terraform/services/beyondcorp/data_source_google_beyondcorp_app_gateway.go @@ -38,7 +38,17 @@ func dataSourceGoogleBeyondcorpAppGatewayRead(d *schema.ResourceData, meta inter return err } - d.SetId(fmt.Sprintf("projects/%s/locations/%s/appGateways/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/locations/%s/appGateways/%s", project, region, name) + d.SetId(id) - return resourceBeyondcorpAppGatewayRead(d, meta) + err = resourceBeyondcorpAppGatewayRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/bigquery/data_source_google_bigquery_default_service_account.go b/mmv1/third_party/terraform/services/bigquery/data_source_google_bigquery_default_service_account.go index cc1e4f0a6d2a..d25349166440 100644 --- a/mmv1/third_party/terraform/services/bigquery/data_source_google_bigquery_default_service_account.go +++ b/mmv1/third_party/terraform/services/bigquery/data_source_google_bigquery_default_service_account.go @@ -43,7 +43,7 @@ func dataSourceGoogleBigqueryDefaultServiceAccountRead(d *schema.ResourceData, m projectResource, err := config.NewBigQueryClient(userAgent).Projects.GetServiceAccount(project).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, "BigQuery service account not found") + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Project %q BigQuery service account", project), fmt.Sprintf("Project %q BigQuery service account", project)) } d.SetId(projectResource.Email) diff --git a/mmv1/third_party/terraform/services/billing/data_source_google_billing_account.go b/mmv1/third_party/terraform/services/billing/data_source_google_billing_account.go index 35faf461500d..7c47a741c13c 100644 --- a/mmv1/third_party/terraform/services/billing/data_source_google_billing_account.go +++ b/mmv1/third_party/terraform/services/billing/data_source_google_billing_account.go @@ -64,7 +64,7 @@ func dataSourceBillingAccountRead(d *schema.ResourceData, meta interface{}) erro if v, ok := d.GetOk("billing_account"); ok { resp, err := config.NewBillingClient(userAgent).BillingAccounts.Get(CanonicalBillingAccountName(v.(string))).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Billing Account Not Found : %s", v)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Billing Account Not Found : %s", v), CanonicalBillingAccountName(v.(string))) } if openOk && resp.Open != open.(bool) { diff --git a/mmv1/third_party/terraform/services/cloudbuild/data_source_google_cloudbuild_trigger.go b/mmv1/third_party/terraform/services/cloudbuild/data_source_google_cloudbuild_trigger.go index 499f4930dcb4..274a8e6e1dad 100644 --- a/mmv1/third_party/terraform/services/cloudbuild/data_source_google_cloudbuild_trigger.go +++ b/mmv1/third_party/terraform/services/cloudbuild/data_source_google_cloudbuild_trigger.go @@ -32,7 +32,16 @@ func dataSourceGoogleCloudBuildTriggerRead(d *schema.ResourceData, meta interfac } id = strings.ReplaceAll(id, "/locations/global/", "/") - d.SetId(id) - return resourceCloudBuildTriggerRead(d, meta) + + err = resourceCloudBuildTriggerRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/cloudfunctions/data_source_google_cloudfunctions_function.go b/mmv1/third_party/terraform/services/cloudfunctions/data_source_google_cloudfunctions_function.go index 04c0463dbf49..5255c37268df 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions/data_source_google_cloudfunctions_function.go +++ b/mmv1/third_party/terraform/services/cloudfunctions/data_source_google_cloudfunctions_function.go @@ -1,6 +1,8 @@ package cloudfunctions import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -48,5 +50,9 @@ func dataSourceGoogleCloudFunctionsFunctionRead(d *schema.ResourceData, meta int return err } + if d.Id() == "" { + return fmt.Errorf("%s not found", cloudFuncId.CloudFunctionId()) + } + return nil } diff --git a/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function.go b/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function.go index f340b7608cc6..6769c2701231 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function.go +++ b/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function.go @@ -32,12 +32,17 @@ func dataSourceGoogleCloudFunctions2FunctionRead(d *schema.ResourceData, meta in return err } - d.SetId(fmt.Sprintf("projects/%s/locations/%s/functions/%s", project, d.Get("location").(string), d.Get("name").(string))) + id := fmt.Sprintf("projects/%s/locations/%s/functions/%s", project, d.Get("location").(string), d.Get("name").(string)) + d.SetId(id) err = resourceCloudfunctions2functionRead(d, meta) if err != nil { return err } + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_group_memberships.go.erb b/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_group_memberships.go.erb index 0035138b50d1..e397219ae527 100644 --- a/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_group_memberships.go.erb +++ b/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_group_memberships.go.erb @@ -85,7 +85,7 @@ func dataSourceGoogleCloudIdentityGroupMembershipsRead(d *schema.ResourceData, m return nil }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroupMemberships %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroupMemberships %q", d.Id()), "") } if err := d.Set("memberships", result); err != nil { diff --git a/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_groups.go.erb b/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_groups.go.erb index 848366d3e4eb..3295619a25f9 100644 --- a/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_groups.go.erb +++ b/mmv1/third_party/terraform/services/cloudidentity/data_source_cloud_identity_groups.go.erb @@ -84,7 +84,7 @@ func dataSourceGoogleCloudIdentityGroupsRead(d *schema.ResourceData, meta interf return nil }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroups %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroups %q", d.Id()), "Groups") } if err := d.Set("groups", result); err != nil { diff --git a/mmv1/third_party/terraform/services/cloudrun/data_source_cloud_run_service.go b/mmv1/third_party/terraform/services/cloudrun/data_source_cloud_run_service.go index f689e97107e4..c674b097723d 100644 --- a/mmv1/third_party/terraform/services/cloudrun/data_source_cloud_run_service.go +++ b/mmv1/third_party/terraform/services/cloudrun/data_source_cloud_run_service.go @@ -28,5 +28,14 @@ func dataSourceGoogleCloudRunServiceRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceCloudRunServiceRead(d, meta) + err = resourceCloudRunServiceRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/composer/data_source_google_composer_environment.go b/mmv1/third_party/terraform/services/composer/data_source_google_composer_environment.go index f536428c6d3c..5b37ab9ad17a 100644 --- a/mmv1/third_party/terraform/services/composer/data_source_google_composer_environment.go +++ b/mmv1/third_party/terraform/services/composer/data_source_google_composer_environment.go @@ -35,7 +35,16 @@ func dataSourceGoogleComposerEnvironmentRead(d *schema.ResourceData, meta interf } envName := d.Get("name").(string) - d.SetId(fmt.Sprintf("projects/%s/locations/%s/environments/%s", project, region, envName)) + id := fmt.Sprintf("projects/%s/locations/%s/environments/%s", project, region, envName) + d.SetId(id) + err = resourceComposerEnvironmentRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } - return resourceComposerEnvironmentRead(d, meta) + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_compute_health_check.go b/mmv1/third_party/terraform/services/compute/data_source_compute_health_check.go index e47066ea9b26..8703c6fcaf7f 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_compute_health_check.go +++ b/mmv1/third_party/terraform/services/compute/data_source_compute_health_check.go @@ -1,6 +1,8 @@ package compute import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -29,5 +31,14 @@ func dataSourceGoogleComputeHealthCheckRead(d *schema.ResourceData, meta interfa } d.SetId(id) - return resourceComputeHealthCheckRead(d, meta) + err = resourceComputeHealthCheckRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_compute_network_endpoint_group.go b/mmv1/third_party/terraform/services/compute/data_source_compute_network_endpoint_group.go index e12c2958b4d5..bb5d4db55efa 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_compute_network_endpoint_group.go +++ b/mmv1/third_party/terraform/services/compute/data_source_compute_network_endpoint_group.go @@ -27,6 +27,7 @@ func DataSourceGoogleComputeNetworkEndpointGroup() *schema.Resource { func dataSourceComputeNetworkEndpointGroupRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*transport_tpg.Config) + id := "" if name, ok := d.GetOk("name"); ok { project, err := tpgresource.GetProject(d, config) if err != nil { @@ -36,7 +37,8 @@ func dataSourceComputeNetworkEndpointGroupRead(d *schema.ResourceData, meta inte if err != nil { return err } - d.SetId(fmt.Sprintf("projects/%s/zones/%s/networkEndpointGroups/%s", project, zone, name.(string))) + id = fmt.Sprintf("projects/%s/zones/%s/networkEndpointGroups/%s", project, zone, name.(string)) + d.SetId(id) } else if selfLink, ok := d.GetOk("self_link"); ok { parsed, err := tpgresource.ParseNetworkEndpointGroupFieldValue(selfLink.(string), d, config) if err != nil { @@ -51,10 +53,20 @@ func dataSourceComputeNetworkEndpointGroupRead(d *schema.ResourceData, meta inte if err := d.Set("project", parsed.Project); err != nil { return fmt.Errorf("Error setting project: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/zones/%s/networkEndpointGroups/%s", parsed.Project, parsed.Zone, parsed.Name)) + id = fmt.Sprintf("projects/%s/zones/%s/networkEndpointGroups/%s", parsed.Project, parsed.Zone, parsed.Name) + d.SetId(id) } else { return errors.New("Must provide either `self_link` or `zone/name`") } - return resourceComputeNetworkEndpointGroupRead(d, meta) + err := resourceComputeNetworkEndpointGroupRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_compute_network_peering.go b/mmv1/third_party/terraform/services/compute/data_source_compute_network_peering.go index fed49bd6ba1e..edc7827e5fbf 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_compute_network_peering.go +++ b/mmv1/third_party/terraform/services/compute/data_source_compute_network_peering.go @@ -35,7 +35,17 @@ func dataSourceComputeNetworkPeeringRead(d *schema.ResourceData, meta interface{ if err != nil { return err } - d.SetId(fmt.Sprintf("%s/%s", networkFieldValue.Name, d.Get("name").(string))) + id := fmt.Sprintf("%s/%s", networkFieldValue.Name, d.Get("name").(string)) + d.SetId(id) - return resourceComputeNetworkPeeringRead(d, meta) + err = resourceComputeNetworkPeeringRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_address.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_address.go index f987531b05d7..f8faecfec4cd 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_address.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_address.go @@ -108,9 +108,11 @@ func dataSourceGoogleComputeAddressRead(d *schema.ResourceData, meta interface{} } name := d.Get("name").(string) + id := fmt.Sprintf("projects/%s/regions/%s/addresses/%s", project, region, name) + address, err := config.NewComputeClient(userAgent).Addresses.Get(project, region, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Address Not Found : %s", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Address Not Found : %s", name), id) } if err := d.Set("address", address.Address); err != nil { @@ -147,7 +149,7 @@ func dataSourceGoogleComputeAddressRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("Error setting region: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/addresses/%s", project, region, name)) + d.SetId(id) return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_bucket.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_bucket.go index b56c80f7c5bc..43e555c17d7b 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_bucket.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_bucket.go @@ -33,7 +33,17 @@ func dataSourceComputeBackendBucketRead(d *schema.ResourceData, meta interface{} return err } - d.SetId(fmt.Sprintf("projects/%s/global/backendBuckets/%s", project, backendBucketName)) + id := fmt.Sprintf("projects/%s/global/backendBuckets/%s", project, backendBucketName) + d.SetId(id) - return resourceComputeBackendBucketRead(d, meta) + err = resourceComputeBackendBucketRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_service.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_service.go index eac09d83ae6a..284dc85905f9 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_service.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_backend_service.go @@ -33,7 +33,17 @@ func dataSourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{ return err } - d.SetId(fmt.Sprintf("projects/%s/global/backendServices/%s", project, serviceName)) + id := fmt.Sprintf("projects/%s/global/backendServices/%s", project, serviceName) + d.SetId(id) - return resourceComputeBackendServiceRead(d, meta) + err = resourceComputeBackendServiceRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_default_service_account.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_default_service_account.go index 59264ef77c8b..a41e4a5225fc 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_default_service_account.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_default_service_account.go @@ -51,7 +51,7 @@ func dataSourceGoogleComputeDefaultServiceAccountRead(d *schema.ResourceData, me projectCompResource, err := config.NewComputeClient(userAgent).Projects.Get(project).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, "GCE default service account") + return transport_tpg.HandleDataSourceNotFoundError(err, d, "GCE default service account", fmt.Sprintf("%q GCE default service account", project)) } serviceAccountName, err := tpgresource.ServiceAccountFQN(projectCompResource.DefaultServiceAccount, d, config) @@ -61,7 +61,7 @@ func dataSourceGoogleComputeDefaultServiceAccountRead(d *schema.ResourceData, me sa, err := config.NewIamClient(userAgent).Projects.ServiceAccounts.Get(serviceAccountName).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Service Account %q", serviceAccountName)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Service Account %q", serviceAccountName), serviceAccountName) } d.SetId(sa.Name) diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_disk.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_disk.go index 9b660c8989e5..7a68c1fa9f7c 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_disk.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_disk.go @@ -29,5 +29,14 @@ func dataSourceGoogleComputeDiskRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceComputeDiskRead(d, meta) + err = resourceComputeDiskRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_forwarding_rule.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_forwarding_rule.go index 9dc06385eb78..555748f1064e 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_forwarding_rule.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_forwarding_rule.go @@ -39,7 +39,17 @@ func dataSourceGoogleComputeForwardingRuleRead(d *schema.ResourceData, meta inte return err } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/forwardingRules/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/regions/%s/forwardingRules/%s", project, region, name) + d.SetId(id) - return resourceComputeForwardingRuleRead(d, meta) + err = resourceComputeForwardingRuleRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_global_address.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_global_address.go index 14e6a8d1a8e0..44239ffdb887 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_global_address.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_global_address.go @@ -89,9 +89,11 @@ func dataSourceGoogleComputeGlobalAddressRead(d *schema.ResourceData, meta inter return err } name := d.Get("name").(string) + id := fmt.Sprintf("projects/%s/global/addresses/%s", project, name) + address, err := config.NewComputeClient(userAgent).GlobalAddresses.Get(project, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Global Address Not Found : %s", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Global Address Not Found : %s", name), id) } if err := d.Set("address", address.Address); err != nil { @@ -124,6 +126,6 @@ func dataSourceGoogleComputeGlobalAddressRead(d *schema.ResourceData, meta inter if err := d.Set("project", project); err != nil { return fmt.Errorf("Error setting project: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/global/addresses/%s", project, name)) + d.SetId(id) return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_ha_vpn_gateway.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_ha_vpn_gateway.go index a5408b608dea..c658e4cdf376 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_ha_vpn_gateway.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_ha_vpn_gateway.go @@ -39,7 +39,17 @@ func dataSourceGoogleComputeHaVpnGatewayRead(d *schema.ResourceData, meta interf return err } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/vpnGateways/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/regions/%s/vpnGateways/%s", project, region, name) + d.SetId(id) - return resourceComputeHaVpnGatewayRead(d, meta) + err = resourceComputeHaVpnGatewayRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance.go.erb b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance.go.erb index 19a49a5b4410..0c885da98bd8 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance.go.erb +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance.go.erb @@ -34,9 +34,11 @@ func dataSourceGoogleComputeInstanceRead(d *schema.ResourceData, meta interface{ return err } + id := fmt.Sprintf("projects/%s/zones/%s/instances/%s", project, zone, name) + instance, err := config.NewComputeClient(userAgent).Instances.Get(project, zone, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Instance %s", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Instance %s", name), id) } md := flattenMetadataBeta(instance.Metadata) diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_group.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_group.go index 7be1e9c072fe..bbe683b335dd 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_group.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_instance_group.go @@ -84,6 +84,7 @@ func DataSourceGoogleComputeInstanceGroup() *schema.Resource { func dataSourceComputeInstanceGroupRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*transport_tpg.Config) + id := "" if name, ok := d.GetOk("name"); ok { zone, err := tpgresource.GetZone(d, config) if err != nil { @@ -93,7 +94,7 @@ func dataSourceComputeInstanceGroupRead(d *schema.ResourceData, meta interface{} if err != nil { return err } - d.SetId(fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", project, zone, name.(string))) + id = fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", project, zone, name.(string)) } else if selfLink, ok := d.GetOk("self_link"); ok { parsed, err := tpgresource.ParseInstanceGroupFieldValue(selfLink.(string), d, config) if err != nil { @@ -108,10 +109,20 @@ func dataSourceComputeInstanceGroupRead(d *schema.ResourceData, meta interface{} if err := d.Set("project", parsed.Project); err != nil { return fmt.Errorf("Error setting project: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", parsed.Project, parsed.Zone, parsed.Name)) + id = fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", parsed.Project, parsed.Zone, parsed.Name) } else { return errors.New("Must provide either `self_link` or `zone/name`") } + d.SetId(id) - return resourceComputeInstanceGroupRead(d, meta) + err := resourceComputeInstanceGroupRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_network.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_network.go index aa12f0b8423e..e0a6b9b63201 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_network.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_network.go @@ -59,9 +59,12 @@ func dataSourceGoogleComputeNetworkRead(d *schema.ResourceData, meta interface{} return err } name := d.Get("name").(string) + + id := fmt.Sprintf("projects/%s/global/networks/%s", project, name) + network, err := config.NewComputeClient(userAgent).Networks.Get(project, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Network Not Found : %s", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Network Not Found : %s", name), id) } if err := d.Set("gateway_ipv4", network.GatewayIPv4); err != nil { return fmt.Errorf("Error setting gateway_ipv4: %s", err) @@ -75,6 +78,6 @@ func dataSourceGoogleComputeNetworkRead(d *schema.ResourceData, meta interface{} if err := d.Set("subnetworks_self_links", network.Subnetworks); err != nil { return fmt.Errorf("Error setting subnetworks_self_links: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/global/networks/%s", project, network.Name)) + d.SetId(id) return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_instance_group.go.erb b/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_instance_group.go.erb index 43c8499ce26b..b4820f426979 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_instance_group.go.erb +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_instance_group.go.erb @@ -104,11 +104,11 @@ func dataSourceComputeRegionInstanceGroupRead(d *schema.ResourceData, meta inter if err != nil { return err } - + id := fmt.Sprintf("projects/%s/regions/%s/instanceGroups/%s", project, region, name) instanceGroup, err := config.NewComputeClient(userAgent).RegionInstanceGroups.Get( project, region, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Region Instance Group %q", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Region Instance Group %q", name), id) } members, err := config.NewComputeClient(userAgent).RegionInstanceGroups.ListInstances( @@ -129,7 +129,7 @@ func dataSourceComputeRegionInstanceGroupRead(d *schema.ResourceData, meta inter return fmt.Errorf("Error setting instances: %s", err) } } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/instanceGroups/%s", project, region, name)) + d.SetId(id) if err := d.Set("self_link", instanceGroup.SelfLink); err != nil { return fmt.Errorf("Error setting self_link: %s", err) } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_network_endpoint_group.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_network_endpoint_group.go index 0147cd280d3d..3834a12ce9bf 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_network_endpoint_group.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_network_endpoint_group.go @@ -26,6 +26,7 @@ func DataSourceGoogleComputeRegionNetworkEndpointGroup() *schema.Resource { func dataSourceComputeRegionNetworkEndpointGroupRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*transport_tpg.Config) + id := "" if name, ok := d.GetOk("name"); ok { project, err := tpgresource.GetProject(d, config) if err != nil { @@ -36,7 +37,7 @@ func dataSourceComputeRegionNetworkEndpointGroupRead(d *schema.ResourceData, met return err } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/networkEndpointGroups/%s", project, region, name.(string))) + id = fmt.Sprintf("projects/%s/regions/%s/networkEndpointGroups/%s", project, region, name.(string)) } else if selfLink, ok := d.GetOk("self_link"); ok { parsed, err := tpgresource.ParseNetworkEndpointGroupRegionalFieldValue(selfLink.(string), d, config) if err != nil { @@ -52,10 +53,19 @@ func dataSourceComputeRegionNetworkEndpointGroupRead(d *schema.ResourceData, met return fmt.Errorf("Error setting region: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/networkEndpointGroups/%s", parsed.Project, parsed.Region, parsed.Name)) + id = fmt.Sprintf("projects/%s/regions/%s/networkEndpointGroups/%s", parsed.Project, parsed.Region, parsed.Name) } else { return errors.New("Must provide either `self_link` or `region/name`") } + d.SetId(id) + err := resourceComputeRegionNetworkEndpointGroupRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } - return resourceComputeRegionNetworkEndpointGroupRead(d, meta) + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_ssl_certificate.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_ssl_certificate.go index a42e9bc85491..17305595d0a6 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_ssl_certificate.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_region_ssl_certificate.go @@ -33,7 +33,16 @@ func dataSourceComputeRegionSslCertificateRead(d *schema.ResourceData, meta inte return err } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/sslCertificates/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/regions/%s/sslCertificates/%s", project, region, name) + d.SetId(id) - return resourceComputeRegionSslCertificateRead(d, meta) + err = resourceComputeRegionSslCertificateRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_resource_policy.go.erb b/mmv1/third_party/terraform/services/compute/data_source_google_compute_resource_policy.go.erb index 3485a7051fe3..ae8d93646032 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_resource_policy.go.erb +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_resource_policy.go.erb @@ -36,7 +36,17 @@ func dataSourceGoogleComputeResourcePolicyRead(d *schema.ResourceData, meta inte return err } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", project, region, name)) + id := fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", project, region, name) + d.SetId(id) - return resourceComputeResourcePolicyRead(d, meta) + err = resourceComputeResourcePolicyRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_router.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_router.go index 01f1ab0218e6..af235d576544 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_router.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_router.go @@ -1,6 +1,8 @@ package compute import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" ) @@ -22,5 +24,13 @@ func dataSourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error routerName := d.Get("name").(string) d.SetId(routerName) - return resourceComputeRouterRead(d, meta) + err := resourceComputeRouterRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", routerName) + } + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_router_nat.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_router_nat.go index b9f8fd1dae48..b74823b94b21 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_router_nat.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_router_nat.go @@ -31,5 +31,14 @@ func dataSourceGoogleComputeRouterNatRead(d *schema.ResourceData, meta interface } d.SetId(id) - return resourceComputeRouterNatRead(d, meta) + err = resourceComputeRouterNatRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_certificate.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_certificate.go index 20e9bf9d4110..31cc3426988d 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_certificate.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_certificate.go @@ -33,7 +33,17 @@ func dataSourceComputeSslCertificateRead(d *schema.ResourceData, meta interface{ } certificateName := d.Get("name").(string) - d.SetId(fmt.Sprintf("projects/%s/global/sslCertificates/%s", project, certificateName)) + id := fmt.Sprintf("projects/%s/global/sslCertificates/%s", project, certificateName) + d.SetId(id) - return resourceComputeSslCertificateRead(d, meta) + err = resourceComputeSslCertificateRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_policy.go b/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_policy.go index 8710928be8e4..1266e7370867 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_policy.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_ssl_policy.go @@ -33,7 +33,17 @@ func datasourceComputeSslPolicyRead(d *schema.ResourceData, meta interface{}) er } policyName := d.Get("name").(string) - d.SetId(fmt.Sprintf("projects/%s/global/sslPolicies/%s", project, policyName)) + id := fmt.Sprintf("projects/%s/global/sslPolicies/%s", project, policyName) + d.SetId(id) - return resourceComputeSslPolicyRead(d, meta) + err = resourceComputeSslPolicyRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_subnetwork.go.erb b/mmv1/third_party/terraform/services/compute/data_source_google_compute_subnetwork.go.erb index 5652ba319f87..5af117f5893d 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_subnetwork.go.erb +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_subnetwork.go.erb @@ -90,10 +90,11 @@ func dataSourceGoogleComputeSubnetworkRead(d *schema.ResourceData, meta interfac if err != nil { return err } + id := fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", project, region, name) subnetwork, err := config.NewComputeClient(userAgent).Subnetworks.Get(project, region, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Subnetwork Not Found : %s", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Subnetwork Not Found : %s", name), id) } if err := d.Set("ip_cidr_range", subnetwork.IpCidrRange); err != nil { @@ -127,7 +128,7 @@ func dataSourceGoogleComputeSubnetworkRead(d *schema.ResourceData, meta interfac return fmt.Errorf("Error setting secondary_ip_range: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", project, region, name)) + d.SetId(id) return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_compute_vpn_gateway.go.erb b/mmv1/third_party/terraform/services/compute/data_source_google_compute_vpn_gateway.go.erb index e11c1711211b..ba7f79403e9d 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_compute_vpn_gateway.go.erb +++ b/mmv1/third_party/terraform/services/compute/data_source_google_compute_vpn_gateway.go.erb @@ -72,12 +72,13 @@ func dataSourceGoogleComputeVpnGatewayRead(d *schema.ResourceData, meta interfac } name := d.Get("name").(string) + id := fmt.Sprintf("projects/%s/regions/%s/targetVpnGateways/%s", project, region, name) vpnGatewaysService := compute.NewTargetVpnGatewaysService(config.NewComputeClient(userAgent)) gateway, err := vpnGatewaysService.Get(project, region, name).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("VPN Gateway Not Found : %s", name)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("VPN Gateway Not Found : %s", name), id) } if err := d.Set("network", tpgresource.ConvertSelfLinkToV1(gateway.Network)); err != nil { return fmt.Errorf("Error setting network: %s", err) @@ -94,6 +95,6 @@ func dataSourceGoogleComputeVpnGatewayRead(d *schema.ResourceData, meta interfac if err := d.Set("project", project); err != nil { return fmt.Errorf("Error setting project: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/regions/%s/targetVpnGateways/%s", project, region, name)) + d.SetId(id) return nil } diff --git a/mmv1/third_party/terraform/services/compute/data_source_google_global_compute_forwarding_rule.go b/mmv1/third_party/terraform/services/compute/data_source_google_global_compute_forwarding_rule.go index 1b25c01babef..ed1bad56b537 100644 --- a/mmv1/third_party/terraform/services/compute/data_source_google_global_compute_forwarding_rule.go +++ b/mmv1/third_party/terraform/services/compute/data_source_google_global_compute_forwarding_rule.go @@ -33,7 +33,17 @@ func dataSourceGoogleComputeGlobalForwardingRuleRead(d *schema.ResourceData, met return err } - d.SetId(fmt.Sprintf("projects/%s/global/forwardingRules/%s", project, name)) + id := fmt.Sprintf("projects/%s/global/forwardingRules/%s", project, name) + d.SetId(id) - return resourceComputeGlobalForwardingRuleRead(d, meta) + err = resourceComputeGlobalForwardingRuleRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil } diff --git a/mmv1/third_party/terraform/services/dataprocmetastore/data_source_dataproc_metastore_service.go.erb b/mmv1/third_party/terraform/services/dataprocmetastore/data_source_dataproc_metastore_service.go.erb index 6a351893759d..76b166edfa33 100644 --- a/mmv1/third_party/terraform/services/dataprocmetastore/data_source_dataproc_metastore_service.go.erb +++ b/mmv1/third_party/terraform/services/dataprocmetastore/data_source_dataproc_metastore_service.go.erb @@ -28,5 +28,13 @@ func dataSourceDataprocMetastoreServiceRead(d *schema.ResourceData, meta interfa return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceDataprocMetastoreServiceRead(d, meta) + err = resourceDataprocMetastoreServiceRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/dns/data_source_dns_keys.go b/mmv1/third_party/terraform/services/dns/data_source_dns_keys.go index 1cc9c8af095f..470815cdc2d0 100644 --- a/mmv1/third_party/terraform/services/dns/data_source_dns_keys.go +++ b/mmv1/third_party/terraform/services/dns/data_source_dns_keys.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/terraform-provider-google/google/fwmodels" "github.com/hashicorp/terraform-provider-google/google/fwresource" "github.com/hashicorp/terraform-provider-google/google/fwtransport" - transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) // Ensure the implementation satisfies the expected interfaces @@ -179,9 +178,7 @@ func (d *GoogleDnsKeysDataSource) Read(ctx context.Context, req datasource.ReadR clientResp, err := d.client.DnsKeys.List(data.Project.ValueString(), data.ManagedZone.ValueString()).Do() if err != nil { - if !transport_tpg.IsGoogleApiErrorWithCode(err, 404) { - resp.Diagnostics.AddError(fmt.Sprintf("Error when reading or editing dataSourceDnsKeys"), err.Error()) - } + resp.Diagnostics.AddError(fmt.Sprintf("Error when reading or editing dataSourceDnsKeys"), err.Error()) // Save data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) return diff --git a/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_android_app.go.erb b/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_android_app.go.erb index e9167e5d8d3e..1c8ca39a6f46 100644 --- a/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_android_app.go.erb +++ b/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_android_app.go.erb @@ -37,6 +37,14 @@ func dataSourceGoogleFirebaseAndroidAppRead(d *schema.ResourceData, meta interfa if err := d.Set("name", name); err != nil { return fmt.Errorf("Error setting name: %s", err) } - return resourceFirebaseAndroidAppRead(d, meta) + err = resourceFirebaseAndroidAppRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", name) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_apple_app.go.erb b/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_apple_app.go.erb index 9d2351c22011..8737c2800b1a 100644 --- a/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_apple_app.go.erb +++ b/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_apple_app.go.erb @@ -37,6 +37,14 @@ func dataSourceGoogleFirebaseAppleAppRead(d *schema.ResourceData, meta interface if err := d.Set("name", name); err != nil { return fmt.Errorf("Error setting name: %s", err) } - return resourceFirebaseAppleAppRead(d, meta) + err = resourceFirebaseAppleAppRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", name) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_web_app.go.erb b/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_web_app.go.erb index d6da3622e83c..4c5616580314 100644 --- a/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_web_app.go.erb +++ b/mmv1/third_party/terraform/services/firebase/data_source_google_firebase_web_app.go.erb @@ -37,6 +37,14 @@ func dataSourceGoogleFirebaseWebAppRead(d *schema.ResourceData, meta interface{} if err := d.Set("name", name); err != nil { return fmt.Errorf("Error setting name: %s", err) } - return resourceFirebaseWebAppRead(d, meta) + err = resourceFirebaseWebAppRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", name) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/firebasehosting/data_source_google_firebase_hosting_channel.go.erb b/mmv1/third_party/terraform/services/firebasehosting/data_source_google_firebase_hosting_channel.go.erb index c8cd9e60a3a1..993392fd2b1c 100644 --- a/mmv1/third_party/terraform/services/firebasehosting/data_source_google_firebase_hosting_channel.go.erb +++ b/mmv1/third_party/terraform/services/firebasehosting/data_source_google_firebase_hosting_channel.go.erb @@ -31,6 +31,14 @@ func dataSourceGoogleFirebaseHostingChannelRead(d *schema.ResourceData, meta int } d.SetId(id) - return resourceFirebaseHostingChannelRead(d, meta) + err = resourceFirebaseHostingChannelRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool.go.erb b/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool.go.erb index 88588781b10d..6df5264d41b5 100644 --- a/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool.go.erb +++ b/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool.go.erb @@ -31,7 +31,15 @@ func dataSourceIAMBetaWorkloadIdentityPoolRead(d *schema.ResourceData, meta inte return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceIAMBetaWorkloadIdentityPoolRead(d, meta) + err = resourceIAMBetaWorkloadIdentityPoolRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool_provider.go.erb b/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool_provider.go.erb index 0aef39e9cfbc..582cd395c5fb 100644 --- a/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool_provider.go.erb +++ b/mmv1/third_party/terraform/services/iambeta/data_source_iam_beta_workload_identity_pool_provider.go.erb @@ -32,7 +32,15 @@ func dataSourceIAMBetaWorkloadIdentityPoolProviderRead(d *schema.ResourceData, m return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceIAMBetaWorkloadIdentityPoolProviderRead(d, meta) + err = resourceIAMBetaWorkloadIdentityPoolProviderRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/iap/data_source_iap_client.go b/mmv1/third_party/terraform/services/iap/data_source_iap_client.go index 6cd3a863188d..736e18da0fe3 100644 --- a/mmv1/third_party/terraform/services/iap/data_source_iap_client.go +++ b/mmv1/third_party/terraform/services/iap/data_source_iap_client.go @@ -27,5 +27,13 @@ func dataSourceGoogleIapClientRead(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceIapClientRead(d, meta) + err = resourceIapClientRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key.go b/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key.go index 84c124eba250..0d39492d0f27 100644 --- a/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key.go +++ b/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key.go @@ -1,6 +1,8 @@ package kms import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -31,7 +33,16 @@ func dataSourceGoogleKmsCryptoKeyRead(d *schema.ResourceData, meta interface{}) Name: d.Get("name").(string), } - d.SetId(cryptoKeyId.CryptoKeyId()) + id := cryptoKeyId.CryptoKeyId() + d.SetId(id) + + err = resourceKMSCryptoKeyRead(d, meta) + if err != nil { + return err + } - return resourceKMSCryptoKeyRead(d, meta) + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key_version.go b/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key_version.go index eb7253f2c674..21192c68ea48 100644 --- a/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key_version.go +++ b/mmv1/third_party/terraform/services/kms/data_source_google_kms_crypto_key_version.go @@ -87,7 +87,7 @@ func dataSourceGoogleKmsCryptoKeyVersionRead(d *schema.ResourceData, meta interf UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("KmsCryptoKeyVersion %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("KmsCryptoKeyVersion %q", d.Id()), url) } if err := d.Set("version", flattenKmsCryptoKeyVersionVersion(res["name"], d)); err != nil { @@ -120,7 +120,7 @@ func dataSourceGoogleKmsCryptoKeyVersionRead(d *schema.ResourceData, meta interf UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("KmsCryptoKey %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("KmsCryptoKey %q", d.Id()), url) } if res["purpose"] == "ASYMMETRIC_SIGN" || res["purpose"] == "ASYMMETRIC_DECRYPT" { diff --git a/mmv1/third_party/terraform/services/kms/data_source_google_kms_key_ring.go b/mmv1/third_party/terraform/services/kms/data_source_google_kms_key_ring.go index ae1bc4f73199..7a47f9b798ef 100644 --- a/mmv1/third_party/terraform/services/kms/data_source_google_kms_key_ring.go +++ b/mmv1/third_party/terraform/services/kms/data_source_google_kms_key_ring.go @@ -1,6 +1,8 @@ package kms import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -31,7 +33,16 @@ func dataSourceGoogleKmsKeyRingRead(d *schema.ResourceData, meta interface{}) er Location: d.Get("location").(string), Project: project, } - d.SetId(keyRingId.KeyRingId()) + id := keyRingId.KeyRingId() + d.SetId(id) + + err = resourceKMSKeyRingRead(d, meta) + if err != nil { + return err + } - return resourceKMSKeyRingRead(d, meta) + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/logging/data_source_google_logging_project_cmek_settings.go b/mmv1/third_party/terraform/services/logging/data_source_google_logging_project_cmek_settings.go index a2b30a6e414a..f839cbe7a868 100644 --- a/mmv1/third_party/terraform/services/logging/data_source_google_logging_project_cmek_settings.go +++ b/mmv1/third_party/terraform/services/logging/data_source_google_logging_project_cmek_settings.go @@ -85,7 +85,7 @@ func dataSourceGoogleLoggingProjectCmekSettingsRead(d *schema.ResourceData, meta UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("LoggingProjectCmekSettings %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("LoggingProjectCmekSettings %q", d.Id()), url) } d.SetId(fmt.Sprintf("projects/%s/cmekSettings", project)) diff --git a/mmv1/third_party/terraform/services/logging/data_source_google_logging_sink.go b/mmv1/third_party/terraform/services/logging/data_source_google_logging_sink.go index 64788602d8d7..95cf8663a709 100644 --- a/mmv1/third_party/terraform/services/logging/data_source_google_logging_sink.go +++ b/mmv1/third_party/terraform/services/logging/data_source_google_logging_sink.go @@ -33,7 +33,7 @@ func dataSourceGoogleLoggingSinkRead(d *schema.ResourceData, meta interface{}) e sink, err := config.NewLoggingClient(userAgent).Sinks.Get(sinkId).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Logging Sink %s", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Logging Sink %s", d.Id()), sinkId) } if err := flattenResourceLoggingSink(d, sink); err != nil { diff --git a/mmv1/third_party/terraform/services/privateca/data_source_certificate_authority.go b/mmv1/third_party/terraform/services/privateca/data_source_certificate_authority.go index 1c72eda30b86..b2beeb943b01 100644 --- a/mmv1/third_party/terraform/services/privateca/data_source_certificate_authority.go +++ b/mmv1/third_party/terraform/services/privateca/data_source_certificate_authority.go @@ -73,7 +73,7 @@ func dataSourcePrivatecaCertificateAuthorityRead(d *schema.ResourceData, meta in UserAgent: userAgent, }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("PrivatecaCertificateAuthority %q", d.Id())) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("PrivatecaCertificateAuthority %q", d.Id()), url) } if err := d.Set("pem_csr", res["pemCsr"]); err != nil { return fmt.Errorf("Error fetching CertificateAuthority: %s", err) diff --git a/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_subscription.go b/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_subscription.go index 745315ad39fd..2e0b49ecb368 100644 --- a/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_subscription.go +++ b/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_subscription.go @@ -28,5 +28,13 @@ func dataSourceGooglePubsubSubscriptionRead(d *schema.ResourceData, meta interfa return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourcePubsubSubscriptionRead(d, meta) + err = resourcePubsubSubscriptionRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_topic.go b/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_topic.go index 9e0fbb909b11..158d1c600535 100644 --- a/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_topic.go +++ b/mmv1/third_party/terraform/services/pubsub/data_source_pubsub_topic.go @@ -28,5 +28,13 @@ func dataSourceGooglePubsubTopicRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourcePubsubTopicRead(d, meta) + err = resourcePubsubTopicRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/redis/data_source_redis_instance.go b/mmv1/third_party/terraform/services/redis/data_source_redis_instance.go index b3da20ecba44..2dd7ad098b71 100644 --- a/mmv1/third_party/terraform/services/redis/data_source_redis_instance.go +++ b/mmv1/third_party/terraform/services/redis/data_source_redis_instance.go @@ -1,6 +1,8 @@ package redis import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -29,5 +31,13 @@ func dataSourceGoogleRedisInstanceRead(d *schema.ResourceData, meta interface{}) } d.SetId(id) - return resourceRedisInstanceRead(d, meta) + err = resourceRedisInstanceRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder.go index fa3099bb8bd5..fb95137a83cc 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder.go @@ -61,13 +61,14 @@ func dataSourceFolderRead(d *schema.ResourceData, meta interface{}) error { return err } - d.SetId(canonicalFolderName(d.Get("folder").(string))) + id := canonicalFolderName(d.Get("folder").(string)) + d.SetId(id) if err := resourceGoogleFolderRead(d, meta); err != nil { return err } // If resource doesn't exist, read will not set ID and we should return error. if d.Id() == "" { - return nil + return fmt.Errorf("%s not found", id) } if v, ok := d.GetOk("lookup_organization"); ok && v.(bool) { diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder_organization_policy.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder_organization_policy.go index a0bbf3fbd779..aa7249c8e99b 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder_organization_policy.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_folder_organization_policy.go @@ -22,7 +22,16 @@ func DataSourceGoogleFolderOrganizationPolicy() *schema.Resource { func datasourceGoogleFolderOrganizationPolicyRead(d *schema.ResourceData, meta interface{}) error { - d.SetId(fmt.Sprintf("%s/%s", d.Get("folder"), d.Get("constraint"))) + id := fmt.Sprintf("%s/%s", d.Get("folder"), d.Get("constraint")) + d.SetId(id) - return resourceGoogleFolderOrganizationPolicyRead(d, meta) + err := resourceGoogleFolderOrganizationPolicyRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_iam_role.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_iam_role.go index 83639d864e95..aad1818e1624 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_iam_role.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_iam_role.go @@ -43,7 +43,7 @@ func dataSourceGoogleIamRoleRead(d *schema.ResourceData, meta interface{}) error roleName := d.Get("name").(string) role, err := config.NewIamClient(userAgent).Roles.Get(roleName).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Error reading IAM Role %s: %s", roleName, err)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Error reading IAM Role %s: %s", roleName, err), roleName) } d.SetId(role.Name) diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_organization.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_organization.go index d600eebddaa9..294a1b652aef 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_organization.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_organization.go @@ -103,7 +103,7 @@ func dataSourceOrganizationRead(d *schema.ResourceData, meta interface{}) error Timeout: d.Timeout(schema.TimeoutRead), }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Organization Not Found : %s", v)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Organization Not Found : %s", v), canonicalOrganizationName(v.(string))) } organization = resp diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_organization_policy.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_organization_policy.go index 597b51beb943..6aaa7d54dcfc 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_organization_policy.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_organization_policy.go @@ -22,7 +22,16 @@ func DataSourceGoogleProjectOrganizationPolicy() *schema.Resource { func datasourceGoogleProjectOrganizationPolicyRead(d *schema.ResourceData, meta interface{}) error { - d.SetId(fmt.Sprintf("%s:%s", d.Get("project"), d.Get("constraint"))) + id := fmt.Sprintf("%s:%s", d.Get("project"), d.Get("constraint")) + d.SetId(id) - return resourceGoogleProjectOrganizationPolicyRead(d, meta) + err := resourceGoogleProjectOrganizationPolicyRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_service.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_service.go index d056b6489828..7bcaa985ca2d 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_service.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_project_service.go @@ -28,5 +28,13 @@ func dataSourceGoogleProjectServiceRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceGoogleProjectServiceRead(d, meta) + err = resourceGoogleProjectServiceRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account.go index c917c396dfbc..15b075a1e763 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account.go @@ -59,7 +59,7 @@ func dataSourceGoogleServiceAccountRead(d *schema.ResourceData, meta interface{} sa, err := config.NewIamClient(userAgent).Projects.ServiceAccounts.Get(serviceAccountName).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Service Account %q", serviceAccountName)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Service Account %q", serviceAccountName), serviceAccountName) } d.SetId(sa.Name) diff --git a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account_key.go b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account_key.go index d3ab027a8cf0..95b47a88cc79 100644 --- a/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account_key.go +++ b/mmv1/third_party/terraform/services/resourcemanager/data_source_google_service_account_key.go @@ -66,7 +66,7 @@ func dataSourceGoogleServiceAccountKeyRead(d *schema.ResourceData, meta interfac // Confirm the service account key exists sak, err := config.NewIamClient(userAgent).Projects.ServiceAccounts.Keys.Get(keyName).PublicKeyType(publicKeyType).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Service Account Key %q", keyName)) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Service Account Key %q", keyName), keyName) } d.SetId(sak.Name) diff --git a/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_config.go.erb b/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_config.go.erb index 1d2ae6c688e4..eca8279a8ae3 100644 --- a/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_config.go.erb +++ b/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_config.go.erb @@ -31,6 +31,14 @@ func dataSourceGoogleRuntimeconfigConfigRead(d *schema.ResourceData, meta interf return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceRuntimeconfigConfigRead(d, meta) + err = resourceRuntimeconfigConfigRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end %> diff --git a/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_variable.go.erb b/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_variable.go.erb index 3d3538dca306..9531af6cda41 100644 --- a/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_variable.go.erb +++ b/mmv1/third_party/terraform/services/runtimeconfig/data_source_runtimeconfig_variable.go.erb @@ -33,7 +33,15 @@ func dataSourceGoogleRuntimeconfigVariableRead(d *schema.ResourceData, meta inte return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceRuntimeconfigVariableRead(d, meta) + err = resourceRuntimeconfigVariableRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> diff --git a/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret.go b/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret.go index 6f424b7cd691..a7a725dccfa5 100644 --- a/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret.go +++ b/mmv1/third_party/terraform/services/secretmanager/data_source_secret_manager_secret.go @@ -26,5 +26,13 @@ func dataSourceSecretManagerSecretRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceSecretManagerSecretRead(d, meta) + err = resourceSecretManagerSecretRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/sourcerepo/data_source_sourcerepo_repository.go b/mmv1/third_party/terraform/services/sourcerepo/data_source_sourcerepo_repository.go index 5fa2a433c7bf..03dd46452142 100644 --- a/mmv1/third_party/terraform/services/sourcerepo/data_source_sourcerepo_repository.go +++ b/mmv1/third_party/terraform/services/sourcerepo/data_source_sourcerepo_repository.go @@ -31,5 +31,13 @@ func dataSourceGoogleSourceRepoRepositoryRead(d *schema.ResourceData, meta inter } d.SetId(id) - return resourceSourceRepoRepositoryRead(d, meta) + err = resourceSourceRepoRepositoryRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/spanner/data_source_spanner_instance.go b/mmv1/third_party/terraform/services/spanner/data_source_spanner_instance.go index 26dff8a17c7d..4c1fb9a0c563 100644 --- a/mmv1/third_party/terraform/services/spanner/data_source_spanner_instance.go +++ b/mmv1/third_party/terraform/services/spanner/data_source_spanner_instance.go @@ -32,5 +32,13 @@ func dataSourceSpannerInstanceRead(d *schema.ResourceData, meta interface{}) err } d.SetId(id) - return resourceSpannerInstanceRead(d, meta) + err = resourceSpannerInstanceRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/sql/data_source_sql_database.go b/mmv1/third_party/terraform/services/sql/data_source_sql_database.go index 264cde5a1f4f..5c4696314c59 100644 --- a/mmv1/third_party/terraform/services/sql/data_source_sql_database.go +++ b/mmv1/third_party/terraform/services/sql/data_source_sql_database.go @@ -27,11 +27,15 @@ func dataSourceSqlDatabaseRead(d *schema.ResourceData, meta interface{}) error { if err != nil { return fmt.Errorf("Error fetching project for Database: %s", err) } - d.SetId(fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, d.Get("instance").(string), d.Get("name").(string))) + id := fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, d.Get("instance").(string), d.Get("name").(string)) + d.SetId(id) err = resourceSQLDatabaseRead(d, meta) if err != nil { return err } + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } if err := d.Set("deletion_policy", nil); err != nil { return fmt.Errorf("Error setting deletion_policy: %s", err) } diff --git a/mmv1/third_party/terraform/services/sql/data_source_sql_database_instance.go b/mmv1/third_party/terraform/services/sql/data_source_sql_database_instance.go index 9aac126ad1e9..e9135ba07723 100644 --- a/mmv1/third_party/terraform/services/sql/data_source_sql_database_instance.go +++ b/mmv1/third_party/terraform/services/sql/data_source_sql_database_instance.go @@ -1,6 +1,8 @@ package sql import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-google/google/tpgresource" ) @@ -18,7 +20,15 @@ func DataSourceSqlDatabaseInstance() *schema.Resource { } func dataSourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) error { + id := d.Get("name").(string) + err := resourceSqlDatabaseInstanceRead(d, meta) + if err != nil { + return err + } - return resourceSqlDatabaseInstanceRead(d, meta) + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/sql/data_source_sql_databases.go b/mmv1/third_party/terraform/services/sql/data_source_sql_databases.go index ed4ecc4f4f9d..1662765ab489 100644 --- a/mmv1/third_party/terraform/services/sql/data_source_sql_databases.go +++ b/mmv1/third_party/terraform/services/sql/data_source_sql_databases.go @@ -60,7 +60,7 @@ func dataSourceSqlDatabasesRead(d *schema.ResourceData, meta interface{}) error }) if err != nil { - return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Databases in %q instance", d.Get("instance").(string))) + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("Databases in %q instance", d.Get("instance").(string)), fmt.Sprintf("Databases in %q instance", d.Get("instance").(string))) } flattenedDatabases := flattenDatabases(databases.Items) diff --git a/mmv1/third_party/terraform/services/storage/data_source_google_storage_project_service_account.go b/mmv1/third_party/terraform/services/storage/data_source_google_storage_project_service_account.go index 0b248d5b53ca..188627eb2838 100644 --- a/mmv1/third_party/terraform/services/storage/data_source_google_storage_project_service_account.go +++ b/mmv1/third_party/terraform/services/storage/data_source_google_storage_project_service_account.go @@ -55,7 +55,7 @@ func dataSourceGoogleStorageProjectServiceAccountRead(d *schema.ResourceData, me serviceAccount, err := serviceAccountGetRequest.Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, "GCS service account not found") + return transport_tpg.HandleDataSourceNotFoundError(err, d, "GCS service account not found", fmt.Sprintf("Project %q GCS service account", project)) } if err := d.Set("project", project); err != nil { diff --git a/mmv1/third_party/terraform/services/storagetransfer/data_source_google_storage_transfer_project_service_account.go b/mmv1/third_party/terraform/services/storagetransfer/data_source_google_storage_transfer_project_service_account.go index 4dc7ec9413b1..584791693df6 100644 --- a/mmv1/third_party/terraform/services/storagetransfer/data_source_google_storage_transfer_project_service_account.go +++ b/mmv1/third_party/terraform/services/storagetransfer/data_source_google_storage_transfer_project_service_account.go @@ -47,7 +47,7 @@ func dataSourceGoogleStorageTransferProjectServiceAccountRead(d *schema.Resource serviceAccount, err := config.NewStorageTransferClient(userAgent).GoogleServiceAccounts.Get(project).Do() if err != nil { - return transport_tpg.HandleNotFoundError(err, d, "Google Cloud Storage Transfer service account not found") + return transport_tpg.HandleDataSourceNotFoundError(err, d, "Google Cloud Storage Transfer service account not found", fmt.Sprintf("Project %q Google Cloud Storage Transfer account", project)) } d.SetId(serviceAccount.AccountEmail) diff --git a/mmv1/third_party/terraform/services/vertexai/data_source_vertex_ai_index.go b/mmv1/third_party/terraform/services/vertexai/data_source_vertex_ai_index.go index 50e58e12c221..8cd28fdb7044 100644 --- a/mmv1/third_party/terraform/services/vertexai/data_source_vertex_ai_index.go +++ b/mmv1/third_party/terraform/services/vertexai/data_source_vertex_ai_index.go @@ -29,5 +29,13 @@ func dataSourceVertexAIIndexRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceVertexAIIndexRead(d, meta) + err = resourceVertexAIIndexRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_cluster.go.erb b/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_cluster.go.erb index b5668f99aaee..cdeff513d0e0 100644 --- a/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_cluster.go.erb +++ b/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_cluster.go.erb @@ -28,6 +28,14 @@ func dataSourceVmwareengineClusterRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceVmwareengineClusterRead(d, meta) + err = resourceVmwareengineClusterRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_network.go.erb b/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_network.go.erb index dbbdfa4f2fd8..87465bef390a 100644 --- a/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_network.go.erb +++ b/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_network.go.erb @@ -30,6 +30,14 @@ func dataSourceVmwareengineNetworkRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceVmwareengineNetworkRead(d, meta) + err = resourceVmwareengineNetworkRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_private_cloud.go.erb b/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_private_cloud.go.erb index 800536162504..915240857698 100644 --- a/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_private_cloud.go.erb +++ b/mmv1/third_party/terraform/services/vmwareengine/data_source_google_vmwareengine_private_cloud.go.erb @@ -30,6 +30,14 @@ func dataSourceVmwareenginePrivateCloudRead(d *schema.ResourceData, meta interfa return fmt.Errorf("Error constructing id: %s", err) } d.SetId(id) - return resourceVmwareenginePrivateCloudRead(d, meta) + err = resourceVmwareenginePrivateCloudRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } <% end -%> \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/vpcaccess/data_source_vpc_access_connector.go b/mmv1/third_party/terraform/services/vpcaccess/data_source_vpc_access_connector.go index 7caa852d8ee7..b8b79401c819 100644 --- a/mmv1/third_party/terraform/services/vpcaccess/data_source_vpc_access_connector.go +++ b/mmv1/third_party/terraform/services/vpcaccess/data_source_vpc_access_connector.go @@ -30,5 +30,13 @@ func dataSourceVPCAccessConnectorRead(d *schema.ResourceData, meta interface{}) d.SetId(id) - return resourceVPCAccessConnectorRead(d, meta) + err = resourceVPCAccessConnectorRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + return nil } diff --git a/mmv1/third_party/terraform/transport/transport.go b/mmv1/third_party/terraform/transport/transport.go index 374841b34ec1..01f0fd1a1aa6 100644 --- a/mmv1/third_party/terraform/transport/transport.go +++ b/mmv1/third_party/terraform/transport/transport.go @@ -136,6 +136,15 @@ func HandleNotFoundError(err error, d *schema.ResourceData, resource string) err fmt.Sprintf("Error when reading or editing %s: {{err}}", resource), err) } +func HandleDataSourceNotFoundError(err error, d *schema.ResourceData, resource, url string) error { + if IsGoogleApiErrorWithCode(err, 404) { + return fmt.Errorf("%s not found", url) + } + + return errwrap.Wrapf( + fmt.Sprintf("Error when reading or editing %s: {{err}}", resource), err) +} + func IsGoogleApiErrorWithCode(err error, errCode int) bool { gerr, ok := errwrap.GetType(err, &googleapi.Error{}).(*googleapi.Error) return ok && gerr != nil && gerr.Code == errCode From daa96b5390443ad3900af72aca569382f0126edd Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:59:33 -0700 Subject: [PATCH 033/476] Update doc for gce_persistent_disk_csi_driver_config (#8912) --- .../services/container/resource_container_cluster.go.erb | 2 +- .../terraform/website/docs/r/container_cluster.html.markdown | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb index da88cbb5421d..19b8c98d860b 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb @@ -380,7 +380,7 @@ func ResourceContainerCluster() *schema.Resource { Computed: true, AtLeastOneOf: addonsConfigKeys, MaxItems: 1, - Description: `Whether this cluster should enable the Google Compute Engine Persistent Disk Container Storage Interface (CSI) Driver. Defaults to enabled; set disabled = true to disable.`, + Description: `Whether this cluster should enable the Google Compute Engine Persistent Disk Container Storage Interface (CSI) Driver. Set enabled = true to enable. The Compute Engine persistent disk CSI Driver is enabled by default on newly created clusters for the following versions: Linux clusters: GKE version 1.18.10-gke.2100 or later, or 1.19.3-gke.2100 or later.`, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "enabled": { diff --git a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown index daec72bb7691..e5eb29fe4011 100644 --- a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -426,7 +426,9 @@ Enable/Disable Security Posture API features for the cluster. Structure is [docu All cluster nodes running GKE 1.15 and higher are recreated.** * `gce_persistent_disk_csi_driver_config` - (Optional). - Whether this cluster should enable the Google Compute Engine Persistent Disk Container Storage Interface (CSI) Driver. Defaults to disabled; set `enabled = true` to enabled. + Whether this cluster should enable the Google Compute Engine Persistent Disk Container Storage Interface (CSI) Driver. Set `enabled = true` to enable. + + **Note:** The Compute Engine persistent disk CSI Driver is enabled by default on newly created clusters for the following versions: Linux clusters: GKE version 1.18.10-gke.2100 or later, or 1.19.3-gke.2100 or later. * `gke_backup_agent_config` - (Optional). The status of the Backup for GKE agent addon. It is disabled by default; Set `enabled = true` to enable. From 4050d26b4b8231e643c1e599eb4fef54da9cca66 Mon Sep 17 00:00:00 2001 From: Zeleena Kearney <12972510+zeleena@users.noreply.github.com> Date: Mon, 11 Sep 2023 13:39:20 -0700 Subject: [PATCH 034/476] Fix docs about running tests for the beta provider (#8916) --- docs/content/develop/run-tests.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/develop/run-tests.md b/docs/content/develop/run-tests.md index afdc7fcf4c10..5c6b655991a2 100644 --- a/docs/content/develop/run-tests.md +++ b/docs/content/develop/run-tests.md @@ -92,7 +92,7 @@ aliases: 1. Run acceptance tests for only modified resources. (Full test runs can take over 9 hours.) See [Go's documentation](https://pkg.go.dev/cmd/go#hdr-Testing_flags) for more information about `-run` and other flags. ```bash - make testacc TEST=./google-beta TESTARGS='-run=TestAccContainerNodePool' + make testacc TEST=./google-beta/services/container TESTARGS='-run=TestAccContainerNodePool' ``` @@ -100,7 +100,7 @@ aliases: 1. Optional: Save verbose test output to a file for analysis. ```bash - TF_LOG=DEBUG make testacc TEST=./google-beta TESTARGS='-run=TestAccContainerNodePool_basic' > output.log + TF_LOG=DEBUG make testacc TEST=./google-beta/services/container TESTARGS='-run=TestAccContainerNodePool_basic' > output.log ``` 1. Optional: Debug tests with [Delve](https://github.com/go-delve/delve). See [`dlv test` documentation](https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv_test.md) for information about available flags. From 610bd6c87ce7ac88bacbb32ed8e05b09f39c786a Mon Sep 17 00:00:00 2001 From: sahsagar-google <126025352+sahsagar-google@users.noreply.github.com> Date: Mon, 11 Sep 2023 13:54:56 -0700 Subject: [PATCH 035/476] Add labels field to the GKEHub Scope resource and make it updatable (#8882) * Adding Terraform resources for Tenancy APIs in GKEHub * Segregating MembershipBinding and MembershipRBACRoleBinding to keep things simpler in the review * Fixing the docu URIs * Adding TF support for Tenancy API for Membership Binding * Adding dependent membership binding to the same commit chain * Making Scope un-updatable and replacing hard coded project number with the one from test env * Making Scope RRBAC updatable * Making Namespace immutable * Adding update test cases * Removing all memberships field from Scope since it is no longer supported * Removing all_memberships field for Scope from all test cases * Adding labels field to the GKEHub Scope resource * Fixing typo in the comment --- mmv1/products/gkehub2/Scope.yaml | 8 ++- .../examples/gkehub_scope_basic.tf.erb | 5 ++ .../gkehub2/resource_gke_hub_scope_test.go | 70 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 mmv1/third_party/terraform/services/gkehub2/resource_gke_hub_scope_test.go diff --git a/mmv1/products/gkehub2/Scope.yaml b/mmv1/products/gkehub2/Scope.yaml index 3c9dd36ae6ef..86e1a806ac47 100644 --- a/mmv1/products/gkehub2/Scope.yaml +++ b/mmv1/products/gkehub2/Scope.yaml @@ -15,8 +15,10 @@ name: 'Scope' base_url: 'projects/{{project}}/locations/global/scopes' create_url: 'projects/{{project}}/locations/global/scopes?scopeId={{scope_id}}' +update_url: 'projects/{{project}}/locations/global/scopes/{{scope_id}}' self_link: 'projects/{{project}}/locations/global/scopes/{{scope_id}}' -immutable: true +update_verb: :PATCH +update_mask: true description: | Scope represents a Scope in a Fleet. references: !ruby/object:Api::Resource::ReferenceLinks @@ -113,3 +115,7 @@ properties: - :READY - :DELETING - :UPDATING + - !ruby/object:Api::Type::KeyValuePairs + name: 'labels' + description: | + Labels for this Scope. diff --git a/mmv1/templates/terraform/examples/gkehub_scope_basic.tf.erb b/mmv1/templates/terraform/examples/gkehub_scope_basic.tf.erb index b00de37a00cd..9585375e4e1f 100644 --- a/mmv1/templates/terraform/examples/gkehub_scope_basic.tf.erb +++ b/mmv1/templates/terraform/examples/gkehub_scope_basic.tf.erb @@ -1,3 +1,8 @@ resource "google_gke_hub_scope" "<%= ctx[:primary_resource_id] %>" { scope_id = "tf-test-scope%{random_suffix}" + labels = { + keyb = "valueb" + keya = "valuea" + keyc = "valuec" + } } diff --git a/mmv1/third_party/terraform/services/gkehub2/resource_gke_hub_scope_test.go b/mmv1/third_party/terraform/services/gkehub2/resource_gke_hub_scope_test.go new file mode 100644 index 000000000000..0c3c84e598ab --- /dev/null +++ b/mmv1/third_party/terraform/services/gkehub2/resource_gke_hub_scope_test.go @@ -0,0 +1,70 @@ +package gkehub2_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 TestAccGKEHub2Scope_gkehubScopeBasicExample_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project": envvar.GetTestProjectFromEnv(), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccGKEHub2Scope_gkehubScopeBasicExample_basic(context), + }, + { + ResourceName: "google_gke_hub_scope.scope", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"scope_id"}, + }, + { + Config: testAccGKEHub2Scope_gkehubScopeBasicExample_update(context), + }, + { + ResourceName: "google_gke_hub_scope.scope", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"scope_id"}, + }, + }, + }) +} + +func testAccGKEHub2Scope_gkehubScopeBasicExample_basic(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gke_hub_scope" "scope" { + scope_id = "tf-test-scope%{random_suffix}" + labels = { + keyb = "valueb" + keya = "valuea" + keyc = "valuec" + } +} +`, context) +} + +func testAccGKEHub2Scope_gkehubScopeBasicExample_update(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gke_hub_scope" "scope" { + scope_id = "tf-test-scope%{random_suffix}" + labels = { + updated_keyb = "updated_valueb" + updated_keya = "updated_valuea" + updated_keyc = "updated_valuec" + } +} +`, context) +} From 0f370e2763be4480a7581acd510a9a29c04d26ec Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:55:16 -0700 Subject: [PATCH 036/476] Add sweeper for dataflow_job (#8917) --- .../dataflow/resource_dataflow_job_sweeper.go | 122 ++++++++++++++++++ .../terraform/sweeper/gcp_sweeper_test.go.erb | 1 + 2 files changed, 123 insertions(+) create mode 100644 mmv1/third_party/terraform/services/dataflow/resource_dataflow_job_sweeper.go diff --git a/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job_sweeper.go b/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job_sweeper.go new file mode 100644 index 000000000000..a25ccbc2a0ef --- /dev/null +++ b/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job_sweeper.go @@ -0,0 +1,122 @@ +package dataflow + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("DataflowJob", testSweepDataFlowJob) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepDataFlowJob(region string) error { + resourceName := "DataflowJob" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://dataflow.googleapis.com/v1b3/projects/{{project}}/locations/{{location}}/jobs", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["items"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + if obj["name"] == nil { + log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) + return nil + } + + name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://dataflow.googleapis.com/v1b3/projects/{{project}}/locations/{{location}}/jobs" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/mmv1/third_party/terraform/sweeper/gcp_sweeper_test.go.erb b/mmv1/third_party/terraform/sweeper/gcp_sweeper_test.go.erb index 222990db0d95..d33b3ca37f7d 100644 --- a/mmv1/third_party/terraform/sweeper/gcp_sweeper_test.go.erb +++ b/mmv1/third_party/terraform/sweeper/gcp_sweeper_test.go.erb @@ -18,6 +18,7 @@ import ( _ "github.com/hashicorp/terraform-provider-google/google/services/container" _ "github.com/hashicorp/terraform-provider-google/google/services/containeraws" _ "github.com/hashicorp/terraform-provider-google/google/services/containerazure" + _ "github.com/hashicorp/terraform-provider-google/google/services/dataflow" _ "github.com/hashicorp/terraform-provider-google/google/services/eventarc" _ "github.com/hashicorp/terraform-provider-google/google/services/firebase" _ "github.com/hashicorp/terraform-provider-google/google/services/firebaserules" From 6fa353c9221cde2a4e55aad4a25214e1d63eb0c7 Mon Sep 17 00:00:00 2001 From: Sarah French <15078782+SarahFrench@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:56:16 +0100 Subject: [PATCH 037/476] Add tests around how plugin framework provider configuration code handles `scopes` values (#8874) * Add initial version of plugin framework provider config test affected by inaccessible functions * Refactor provider config tests to use plugin-framework types * Add test case about handling of Unknown values for `project` * Update tests to check values in BOTH the data model and provider config struct after `LoadAndValidateFramework` runs * Add some tests for `credentials` in plugin framework provider, including test case that fails * Update `LoadAndValidateFramework` to take a pointer to the provider data model, so mutations to the data within the function change the original struct This enables tests to track how the data is mutated * Add remaining `credentials` test cases to check PF/SDK config parity * Make tests unset ADC ENV automatically, update comments to tests setting ADC ENV * Add test for behaviour when credentials value is unknown * Add comment referring devs to where unknown value test is implemented * Remove duplicated test case * Fix filename so it's generated correctly * Remove fmt line * Update `project` tests that are affected by `LoadAndValidateFramework` now taking a pointer as an argument * Remove duplication of `defaultClientScopes` info, format `FrameworkProviderConfig` struct definition * Update `FrameworkProviderConfig` to store scopes info using types.List, make field be populated with data * Add initial version of tests for scopes in plugin framework config code * Add remaining tests for `scopes`, update formatting of SDK version of test case * Change (FrameworkProviderConfig).UserProjectOverride to types.Bool (again) --- .../fwtransport/framework_config.go.erb | 46 ++++----- .../fwtransport/framework_config_test.go.erb | 98 +++++++++++++++++++ .../provider/provider_internal_test.go | 18 +--- 3 files changed, 122 insertions(+), 40 deletions(-) diff --git a/mmv1/third_party/terraform/fwtransport/framework_config.go.erb b/mmv1/third_party/terraform/fwtransport/framework_config.go.erb index a97a99cb5a36..51398eddc1de 100644 --- a/mmv1/third_party/terraform/fwtransport/framework_config.go.erb +++ b/mmv1/third_party/terraform/fwtransport/framework_config.go.erb @@ -31,30 +31,25 @@ import ( ) type FrameworkProviderConfig struct { - BillingProject types.String - Client *http.Client - Context context.Context - gRPCLoggingOptions []option.ClientOption - PollInterval time.Duration - Project types.String - Region types.String - Zone types.String - RequestBatcherIam *transport_tpg.RequestBatcher - RequestBatcherServiceUsage *transport_tpg.RequestBatcher - Scopes []string - TokenSource oauth2.TokenSource - UserAgent string - UserProjectOverride types.Bool - - // paths for client setup - <% products.each do |product| -%> - <%= product[:definitions].name -%>BasePath string - <% end -%> -} - -var defaultClientScopes = []string{ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/userinfo.email", + BillingProject types.String + Client *http.Client + Context context.Context + gRPCLoggingOptions []option.ClientOption + PollInterval time.Duration + Project types.String + Region types.String + Zone types.String + RequestBatcherIam *transport_tpg.RequestBatcher + RequestBatcherServiceUsage *transport_tpg.RequestBatcher + Scopes types.List + TokenSource oauth2.TokenSource + UserAgent string + UserProjectOverride types.Bool + + // paths for client setup + <% products.each do |product| -%> + <%= product[:definitions].name -%>BasePath string + <% end -%> } // LoadAndValidateFramework handles the bulk of configuring the provider @@ -101,6 +96,7 @@ func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context, p.BillingProject = data.BillingProject p.Project = data.Project p.Region = data.Region + p.Scopes = data.Scopes p.Zone = data.Zone p.UserProjectOverride = data.UserProjectOverride p.PollInterval = 10 * time.Second @@ -176,7 +172,7 @@ func (p *FrameworkProviderConfig) HandleDefaults(ctx context.Context, data *fwmo if len(data.Scopes.Elements()) == 0 { var d diag.Diagnostics - data.Scopes, d = types.ListValueFrom(ctx, types.StringType, defaultClientScopes) + data.Scopes, d = types.ListValueFrom(ctx, types.StringType, transport_tpg.DefaultClientScopes) diags.Append(d...) if diags.HasError() { return diff --git a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb index 0a2b57c91cdb..d15cbd88ac46 100644 --- a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb +++ b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb @@ -1208,4 +1208,102 @@ func TestFrameworkProvider_LoadAndValidateFramework_impersonateServiceAccountDel // fwtransport.FrameworkProviderConfig does not store impersonate_service_account info, so test does not make assertions on config struct }) } +} + +func TestFrameworkProvider_LoadAndValidateFramework_scopes(t *testing.T) { + + // Note: In the test function we need to set the below fields in test case's fwmodels.ProviderModel value + // this is to stop the code under tests experiencing errors, and could be addressed in future refactoring. + // - Credentials: If we don't set this then the test looks for application default credentials and can fail depending on the machine running the test + // - ImpersonateServiceAccountDelegates: If we don't set this, we get a nil pointer exception ¯\_(ツ)_/¯ + + cases := map[string]struct { + ScopesValue []string + EnvVariables map[string]string + ExpectedDataModelValue []string + ExpectedConfigStructValue []string + SetAsNull bool + SetAsUnknown bool + ExpectError bool + }{ + "scopes are set in the provider config as a list": { + ScopesValue: []string{"fizz", "buzz", "baz"}, + ExpectedDataModelValue: []string{"fizz", "buzz", "baz"}, + ExpectedConfigStructValue: []string{"fizz", "buzz", "baz"}, + }, + "scopes can be left unset in the provider config without any issues, and a default value is used": { + SetAsNull: true, + ExpectedDataModelValue: transport_tpg.DefaultClientScopes, + ExpectedConfigStructValue: transport_tpg.DefaultClientScopes, + }, + // Handling empty values in config + "scopes set as an empty list the field is treated as if it's unset and a default value is used without errors": { + ScopesValue: []string{}, + ExpectedDataModelValue: transport_tpg.DefaultClientScopes, + ExpectedConfigStructValue: transport_tpg.DefaultClientScopes, + }, + // Handling unknown values + "when scopes is an unknown value, the provider treats it as if it's unset and a default value is used without errors (align to SDK behaviour)": { + SetAsUnknown: true, + ExpectedDataModelValue: transport_tpg.DefaultClientScopes, + ExpectedConfigStructValue: transport_tpg.DefaultClientScopes, + }, + } + + for tn, tc := range cases { + t.Run(tn, func(t *testing.T) { + + // Arrange + acctest.UnsetTestProviderConfigEnvs(t) + acctest.SetupTestEnvs(t, tc.EnvVariables) + + ctx := context.Background() + tfVersion := "foobar" + providerversion := "999" + diags := diag.Diagnostics{} + + data := fwmodels.ProviderModel{} + data.Credentials = types.StringValue(transport_tpg.TestFakeCredentialsPath) + impersonateServiceAccountDelegates, _ := types.ListValue(types.StringType, []attr.Value{}) // empty list + data.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates + // Set ImpersonateServiceAccountDelegates depending on test case + if !tc.SetAsNull && !tc.SetAsUnknown { + s, _ := types.ListValueFrom(ctx, types.StringType, tc.ScopesValue) + data.Scopes = s + } + if tc.SetAsNull { + data.Scopes = types.ListNull(types.StringType) + } + if tc.SetAsUnknown { + data.Scopes = types.ListUnknown(types.StringType) + } + + p := fwtransport.FrameworkProviderConfig{} + + // Act + p.LoadAndValidateFramework(ctx, &data, tfVersion, &diags, providerversion) + + // Assert + if diags.HasError() && tc.ExpectError { + return + } + if diags.HasError() && !tc.ExpectError { + for i, err := range diags.Errors() { + num := i + 1 + t.Logf("unexpected error #%d : %s", num, err.Summary()) + } + t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) + } + // Checking mutation of the data model + expectedDm, _ := types.ListValueFrom(ctx, types.StringType, tc.ExpectedDataModelValue) + if !data.Scopes.Equal(expectedDm) { + t.Fatalf("want project in the `fwmodels.ProviderModel` struct to be `%s`, but got the value `%s`", tc.ExpectedDataModelValue, data.Scopes.String()) + } + // Checking the value passed to the config structs + expectedFpc, _ := types.ListValueFrom(ctx, types.StringType, tc.ExpectedConfigStructValue) + if !p.Scopes.Equal(expectedFpc) { + t.Fatalf("want project in the `FrameworkProviderConfig` struct to be `%s`, but got the value `%s`", tc.ExpectedConfigStructValue, p.Scopes.String()) + } + }) + } } \ No newline at end of file diff --git a/mmv1/third_party/terraform/provider/provider_internal_test.go b/mmv1/third_party/terraform/provider/provider_internal_test.go index 343fccc741a7..766b129ecfa4 100644 --- a/mmv1/third_party/terraform/provider/provider_internal_test.go +++ b/mmv1/third_party/terraform/provider/provider_internal_test.go @@ -1255,22 +1255,10 @@ func TestProvider_ProviderConfigure_scopes(t *testing.T) { "scopes are set in the provider config as a list": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, - "scopes": []string{ - "fizz", - "buzz", - "fizzbuzz", - }, - }, - ExpectedSchemaValue: []string{ - "fizz", - "buzz", - "fizzbuzz", - }, - ExpectedConfigValue: []string{ - "fizz", - "buzz", - "fizzbuzz", + "scopes": []string{"fizz", "buzz", "fizzbuzz"}, }, + ExpectedSchemaValue: []string{"fizz", "buzz", "fizzbuzz"}, + ExpectedConfigValue: []string{"fizz", "buzz", "fizzbuzz"}, }, "scopes can be left unset in the provider config without any issues, and a default value is used": { ConfigValues: map[string]interface{}{ From d2ebed8c937be265616c266892e7bc583dae0bbd Mon Sep 17 00:00:00 2001 From: Sarah French <15078782+SarahFrench@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:35:12 +0100 Subject: [PATCH 038/476] Add tests around how plugin framework provider configuration code handles `request_reason` and `request_timeout` values (#8898) * Add initial copy of test cases - some currently fail. * Update test case names for `request_timeout` tests * Comment out tests that will be made to pass in future bug fixes * Change test case names when empty strings/nulls are used, highlight difference between SDK and PF defaults * Add empty string test cases to both SDK and PF tests * Add unknown value test case to PF tests * Update how tests log unexpected error details --- .../fwtransport/framework_config_test.go.erb | 212 +++++++++++++++++- .../provider/provider_internal_test.go | 29 ++- 2 files changed, 232 insertions(+), 9 deletions(-) diff --git a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb index d15cbd88ac46..b356c7728fd3 100644 --- a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb +++ b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb @@ -999,7 +999,7 @@ func TestFrameworkProvider_LoadAndValidateFramework_userProjectOverride(t *testi if diags.HasError() && !tc.ExpectError { for i, err := range diags.Errors() { num := i + 1 - t.Logf("unexpected error #%d : %s", num, err.Summary()) + t.Logf("unexpected error #%d : %s : %s", num, err.Summary(), err.Detail()) } t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) } @@ -1100,7 +1100,7 @@ func TestFrameworkProvider_LoadAndValidateFramework_impersonateServiceAccount(t if diags.HasError() && !tc.ExpectError { for i, err := range diags.Errors() { num := i + 1 - t.Logf("unexpected error #%d : %s", num, err.Summary()) + t.Logf("unexpected error #%d : %s : %s", num, err.Summary(), err.Detail()) } t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) } @@ -1196,7 +1196,7 @@ func TestFrameworkProvider_LoadAndValidateFramework_impersonateServiceAccountDel if diags.HasError() && !tc.ExpectError { for i, err := range diags.Errors() { num := i + 1 - t.Logf("unexpected error #%d : %s", num, err.Summary()) + t.Logf("unexpected error #%d : %s : %s", num, err.Summary(), err.Detail()) } t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) } @@ -1290,7 +1290,7 @@ func TestFrameworkProvider_LoadAndValidateFramework_scopes(t *testing.T) { if diags.HasError() && !tc.ExpectError { for i, err := range diags.Errors() { num := i + 1 - t.Logf("unexpected error #%d : %s", num, err.Summary()) + t.Logf("unexpected error #%d : %s : %s", num, err.Summary(), err.Detail()) } t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) } @@ -1306,4 +1306,206 @@ func TestFrameworkProvider_LoadAndValidateFramework_scopes(t *testing.T) { } }) } -} \ No newline at end of file +} + +func TestFrameworkProvider_LoadAndValidateFramework_requestReason(t *testing.T) { + + // Note: In the test function we need to set the below fields in test case's fwmodels.ProviderModel value + // this is to stop the code under tests experiencing errors, and could be addressed in future refactoring. + // - Credentials: If we don't set this then the test looks for application default credentials and can fail depending on the machine running the test + // - ImpersonateServiceAccountDelegates: If we don't set this, we get a nil pointer exception ¯\_(ツ)_/¯ + + cases := map[string]struct { + ConfigValues fwmodels.ProviderModel + EnvVariables map[string]string + ExpectedDataModelValue basetypes.StringValue + // ExpectedConfigStructValue not used here, as credentials info isn't stored in the config struct + ExpectError bool + }{ + "when request_reason is unset in the config, environment variable CLOUDSDK_CORE_REQUEST_REASON is used": { + ConfigValues: fwmodels.ProviderModel{ + RequestReason: types.StringNull(), + }, + EnvVariables: map[string]string{ + "CLOUDSDK_CORE_REQUEST_REASON": "foo", + }, + ExpectedDataModelValue: types.StringValue("foo"), + }, + "request_reason set in the config is not overridden by environment variables": { + ConfigValues: fwmodels.ProviderModel{ + RequestReason: types.StringValue("value-from-config"), + }, + EnvVariables: map[string]string{ + "CLOUDSDK_CORE_REQUEST_REASON": "value-from-env", + }, + ExpectedDataModelValue: types.StringValue("value-from-config"), + }, + "when no request_reason is provided via config or environment variables, the field remains unset without error": { + ConfigValues: fwmodels.ProviderModel{ + RequestReason: types.StringNull(), + }, + ExpectedDataModelValue: types.StringNull(), + }, + // Handling empty strings in config + // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 + // "when request_reason is set as an empty string in the config it is overridden by environment variables": { + // ConfigValues: fwmodels.ProviderModel{ + // RequestReason: types.StringValue(""), + // }, + // EnvVariables: map[string]string{ + // "CLOUDSDK_CORE_REQUEST_REASON": "foo", + // }, + // ExpectedDataModelValue: types.StringValue("foo"), + // }, + // "when request_reason is set as an empty string in the config the field is treated as if it's unset, without error": { + // ConfigValues: fwmodels.ProviderModel{ + // RequestReason: types.StringValue(""), + // }, + // ExpectedDataModelValue: types.StringNull(), + // }, + // Handling unknown values + // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 + // "when request_timeout is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { + // ConfigValues: fwmodels.ProviderModel{ + // RequestReason: types.StringUnknown(), + // }, + // ExpectedDataModelValue: types.StringNull(), + // }, + } + + for tn, tc := range cases { + t.Run(tn, func(t *testing.T) { + + // Arrange + acctest.UnsetTestProviderConfigEnvs(t) + acctest.SetupTestEnvs(t, tc.EnvVariables) + + ctx := context.Background() + tfVersion := "foobar" + providerversion := "999" + diags := diag.Diagnostics{} + + data := tc.ConfigValues + data.Credentials = types.StringValue(transport_tpg.TestFakeCredentialsPath) + impersonateServiceAccountDelegates, _ := types.ListValue(types.StringType, []attr.Value{}) // empty list + data.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates + + p := fwtransport.FrameworkProviderConfig{} + + // Act + p.LoadAndValidateFramework(ctx, &data, tfVersion, &diags, providerversion) + + // Assert + if diags.HasError() && tc.ExpectError { + return + } + if diags.HasError() && !tc.ExpectError { + for i, err := range diags.Errors() { + num := i + 1 + t.Logf("unexpected error #%d : %s : %s", num, err.Summary(), err.Detail()) + } + t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) + } + // Checking mutation of the data model + if !data.RequestReason.Equal(tc.ExpectedDataModelValue) { + t.Fatalf("want request_reason in the `fwmodels.ProviderModel` struct to be `%s`, but got the value `%s`", tc.ExpectedDataModelValue, data.RequestReason.String()) + } + // fwtransport.FrameworkProviderConfig does not store the request reason info, so test does not make assertions on config struct + }) + } +} + +func TestFrameworkProvider_LoadAndValidateFramework_requestTimeout(t *testing.T) { + + // Note: In the test function we need to set the below fields in test case's fwmodels.ProviderModel value + // this is to stop the code under tests experiencing errors, and could be addressed in future refactoring. + // - Credentials: If we don't set this then the test looks for application default credentials and can fail depending on the machine running the test + // - ImpersonateServiceAccountDelegates: If we don't set this, we get a nil pointer exception ¯\_(ツ)_/¯ + + cases := map[string]struct { + ConfigValues fwmodels.ProviderModel + EnvVariables map[string]string + ExpectedDataModelValue basetypes.StringValue + // ExpectedConfigStructValue not used here, as credentials info isn't stored in the config struct + ExpectError bool + }{ + "if a valid request_timeout is configured in the provider, no error will occur": { + ConfigValues: fwmodels.ProviderModel{ + RequestTimeout: types.StringValue("10s"), + }, + ExpectedDataModelValue: types.StringValue("10s"), + }, + "if an invalid request_timeout is configured in the provider, an error will occur": { + ConfigValues: fwmodels.ProviderModel{ + RequestTimeout: types.StringValue("timeout"), + }, + ExpectError: true, + }, + // In the SDK version of the provider config code, this scenario results in a value of "0s" + // instead of "120s", but the final 'effective' value is also "120s" + // See : https://github.com/hashicorp/terraform-provider-google/blob/09cb850ee64bcd78e4457df70905530c1ed75f19/google/transport/config.go#L1228-L1233 + "when request_timeout is unset in the config, the default value is 120s.": { + ConfigValues: fwmodels.ProviderModel{ + RequestTimeout: types.StringNull(), + }, + ExpectedDataModelValue: types.StringValue("120s"), + }, + // Handling empty strings in config + // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 + // "when request_timeout is set as an empty string, the default value is 120s.": { + // ConfigValues: fwmodels.ProviderModel{ + // RequestTimeout: types.StringValue(""), + // }, + // ExpectedDataModelValue: types.StringValue("120s"), + // }, + // Handling unknown values + // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 + // "when request_timeout is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { + // ConfigValues: fwmodels.ProviderModel{ + // RequestTimeout: types.StringUnknown(), + // }, + // ExpectedDataModelValue: types.StringNull(), + // }, + } + + for tn, tc := range cases { + t.Run(tn, func(t *testing.T) { + + // Arrange + acctest.UnsetTestProviderConfigEnvs(t) + acctest.SetupTestEnvs(t, tc.EnvVariables) + + ctx := context.Background() + tfVersion := "foobar" + providerversion := "999" + diags := diag.Diagnostics{} + + data := tc.ConfigValues + data.Credentials = types.StringValue(transport_tpg.TestFakeCredentialsPath) + impersonateServiceAccountDelegates, _ := types.ListValue(types.StringType, []attr.Value{}) // empty list + data.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates + + p := fwtransport.FrameworkProviderConfig{} + + // Act + p.LoadAndValidateFramework(ctx, &data, tfVersion, &diags, providerversion) + + // Assert + if diags.HasError() && tc.ExpectError { + return + } + if diags.HasError() && !tc.ExpectError { + for i, err := range diags.Errors() { + num := i + 1 + t.Logf("unexpected error #%d : %s : %s", num, err.Summary(), err.Detail()) + } + t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) + } + // Checking mutation of the data model + if !data.RequestTimeout.Equal(tc.ExpectedDataModelValue) { + t.Fatalf("want request_timeout in the `fwmodels.ProviderModel` struct to be `%s`, but got the value `%s`", tc.ExpectedDataModelValue, data.RequestTimeout.String()) + } + // fwtransport.FrameworkProviderConfig does not store the request timeout info, so test does not make assertions on config struct + }) + } +} diff --git a/mmv1/third_party/terraform/provider/provider_internal_test.go b/mmv1/third_party/terraform/provider/provider_internal_test.go index 766b129ecfa4..cfb8fc7254ae 100644 --- a/mmv1/third_party/terraform/provider/provider_internal_test.go +++ b/mmv1/third_party/terraform/provider/provider_internal_test.go @@ -1377,17 +1377,17 @@ func TestProvider_ProviderConfigure_requestTimeout(t *testing.T) { ExpectError: true, ExpectFieldUnset: false, }, - // it's default value is set when RequestTimeout value is 0. - // This can be seen in this part of the config code where the default value is set to 120s + // RequestTimeout is "0s" if unset by the user, and logic elsewhere will supply a different value. + // This can be seen in this part of the config code where the default value is set to "120s" // https://github.com/hashicorp/terraform-provider-google/blob/09cb850ee64bcd78e4457df70905530c1ed75f19/google/transport/config.go#L1228-L1233 - "when config is unset, the value will be 0s in order to set the default value": { + "when request_timeout is unset in the config, the default value is 0s. (initially; this value is subsequently overwritten)": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, }, ExpectedValue: "0s", ExpectFieldUnset: true, }, - "when value is empty, the value will be 0s in order to set the default value": { + "when request_timeout is set as an empty string, the default value is 0s. (initially; this value is subsequently overwritten)": { ConfigValues: map[string]interface{}{ "request_timeout": "", "credentials": transport_tpg.TestFakeCredentialsPath, @@ -1481,6 +1481,27 @@ func TestProvider_ProviderConfigure_requestReason(t *testing.T) { // request_reason unset "credentials": transport_tpg.TestFakeCredentialsPath, }, + ExpectedSchemaValue: "", + ExpectedConfigValue: "", + }, + // Handling empty values in config + "when request_reason is set as an empty string in the config it is overridden by environment variables": { + ConfigValues: map[string]interface{}{ + "request_reason": "", + "credentials": transport_tpg.TestFakeCredentialsPath, + }, + EnvVariables: map[string]string{ + "CLOUDSDK_CORE_REQUEST_REASON": "test", + }, + ExpectedSchemaValue: "test", + ExpectedConfigValue: "test", + }, + "when request_reason is set as an empty string in the config, the field remains unset without error": { + ConfigValues: map[string]interface{}{ + "request_reason": "", + "credentials": transport_tpg.TestFakeCredentialsPath, + }, + ExpectedSchemaValue: "", ExpectedConfigValue: "", }, } From af414091b968548a266a6efa4ab5d216186dd90f Mon Sep 17 00:00:00 2001 From: Edward Sun <42220489+edwardmedia@users.noreply.github.com> Date: Tue, 12 Sep 2023 06:36:50 -0700 Subject: [PATCH 039/476] remove beta in a doc (#8883) Co-authored-by: Edward Sun --- .../website/docs/r/compute_instance_template.html.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/website/docs/r/compute_instance_template.html.markdown b/mmv1/third_party/terraform/website/docs/r/compute_instance_template.html.markdown index 34c4bafdaa77..2d08f340fb6f 100644 --- a/mmv1/third_party/terraform/website/docs/r/compute_instance_template.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/compute_instance_template.html.markdown @@ -318,8 +318,7 @@ The following arguments are supported: this template. This can be specified multiple times for multiple networks. Structure is [documented below](#nested_network_interface). -* `network_performance_config` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html) - Configures network performance settings for the instance created from the +* `network_performance_config` (Optional, Configures network performance settings for the instance created from the template. Structure is [documented below](#nested_network_performance_config). **Note**: [`machine_type`](#machine_type) must be a [supported type](https://cloud.google.com/compute/docs/networking/configure-vm-with-high-bandwidth-configuration), the [`image`](#image) used must include the [`GVNIC`](https://cloud.google.com/compute/docs/networking/using-gvnic#create-instance-gvnic-image) From 37206b2a5ace8b41e6b7c9c781b108d888240bf8 Mon Sep 17 00:00:00 2001 From: sachin purohit Date: Tue, 12 Sep 2023 21:16:16 +0530 Subject: [PATCH 040/476] feat(bigquery): add option to use Non-incremental materialized views (#8725) --- .../bigquery/resource_bigquery_table.go | 14 +++ .../bigquery/resource_bigquery_table_test.go | 113 ++++++++++++++++++ .../docs/r/bigquery_table.html.markdown | 3 + 3 files changed, 130 insertions(+) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index 27a83e8c8d1b..4a2882021e48 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -837,6 +837,14 @@ func ResourceBigQueryTable() *schema.Resource { Description: `Specifies maximum frequency at which this materialized view will be refreshed. The default is 1800000`, }, + "allow_non_incremental_definition": { + Type: schema.TypeBool, + Default: false, + Optional: true, + ForceNew: true, + Description: `Allow non incremental materialized view definition. The default value is false.`, + }, + // Query: [Required] A query whose result is persisted "query": { Type: schema.TypeString, @@ -1982,6 +1990,11 @@ func expandMaterializedView(configured interface{}) *bigquery.MaterializedViewDe mvd.ForceSendFields = append(mvd.ForceSendFields, "RefreshIntervalMs") } + if v, ok := raw["allow_non_incremental_definition"]; ok { + mvd.AllowNonIncrementalDefinition = v.(bool) + mvd.ForceSendFields = append(mvd.ForceSendFields, "AllowNonIncrementalDefinition") + } + return mvd } @@ -1989,6 +2002,7 @@ func flattenMaterializedView(mvd *bigquery.MaterializedViewDefinition) []map[str result := map[string]interface{}{"query": mvd.Query} result["enable_refresh"] = mvd.EnableRefresh result["refresh_interval_ms"] = mvd.RefreshIntervalMs + result["allow_non_incremental_definition"] = mvd.AllowNonIncrementalDefinition return []map[string]interface{}{result} } diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go index e2b9b2991260..bed08d6020c9 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go @@ -487,6 +487,39 @@ func TestAccBigQueryTable_MaterializedView_DailyTimePartioning_Update(t *testing }) } +func TestAccBigQueryTable_MaterializedView_NonIncremental_basic(t *testing.T) { + t.Parallel() + + datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + materialized_viewID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + query := fmt.Sprintf("SELECT count(some_string) as count, some_int, ts FROM `%s.%s` WHERE DATE(ts) = '2019-01-01' GROUP BY some_int, ts", datasetID, tableID) + maxStaleness := "0-0 0 10:0:0" + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableWithMatViewNonIncremental_basic(datasetID, tableID, materialized_viewID, query, maxStaleness), + }, + { + ResourceName: "google_bigquery_table.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection"}, + }, + { + ResourceName: "google_bigquery_table.mv_test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection"}, + }, + }, + }) +} + func TestAccBigQueryExternalDataTable_parquet(t *testing.T) { t.Parallel() @@ -1838,6 +1871,86 @@ resource "google_bigquery_table" "mv_test" { `, datasetID, tableID, mViewID, enable_refresh, refresh_interval, query) } +func testAccBigQueryTableWithMatViewNonIncremental_basic(datasetID, tableID, mViewID, query, maxStaleness string) string { + return fmt.Sprintf(` +resource "google_bigquery_dataset" "test" { + dataset_id = "%s" +} + +resource "google_bigquery_table" "test" { + deletion_protection = false + table_id = "%s" + dataset_id = google_bigquery_dataset.test.dataset_id + + time_partitioning { + type = "DAY" + field = "ts" + require_partition_filter = true + } + clustering = ["some_int", "some_string"] + schema = <The `encryption_configuration` block supports the following arguments: * `kms_key_name` - (Required) The self link or full name of a key which should be used to From cd59a961c24b5ce0e7697e4ae3ee4b4e389d5494 Mon Sep 17 00:00:00 2001 From: Ryan Oaks Date: Tue, 12 Sep 2023 12:20:32 -0400 Subject: [PATCH 041/476] Add roaks3 to onVacationReviewers (#8924) --- .ci/containers/membership-checker/membership.go | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/containers/membership-checker/membership.go b/.ci/containers/membership-checker/membership.go index 26768ddd30ec..58a1ff0f6f70 100644 --- a/.ci/containers/membership-checker/membership.go +++ b/.ci/containers/membership-checker/membership.go @@ -31,6 +31,7 @@ var ( // This is for reviewers who are "on vacation": will not receive new review assignments but will still receive re-requests for assigned PRs. onVacationReviewers = []string{ "slevenick", + "roaks3", } ) From 2d3c0ce9190053d5d4cc0e22afc31ee55e399df2 Mon Sep 17 00:00:00 2001 From: Maciej Murakowski <71409499+mmurakowski-verily@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:22:07 -0400 Subject: [PATCH 042/476] Adding dialogflow_cx_test_case resource (#8879) * Adding dialogflow_cx_test_case resource * Making displayName output-only * Using %parent instead of custom import code * Adding comment clarifying why intent + audio are missing * Making tests exercise updating more fields --- mmv1/products/dialogflowcx/TestCase.yaml | 451 ++++++++++++++++++ .../dialogflowcx_test_case_full.tf.erb | 125 +++++ .../resource_dialogflow_cx_test_case_test.go | 255 ++++++++++ 3 files changed, 831 insertions(+) create mode 100644 mmv1/products/dialogflowcx/TestCase.yaml create mode 100644 mmv1/templates/terraform/examples/dialogflowcx_test_case_full.tf.erb create mode 100644 mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_test_case_test.go diff --git a/mmv1/products/dialogflowcx/TestCase.yaml b/mmv1/products/dialogflowcx/TestCase.yaml new file mode 100644 index 000000000000..e6b02c24d167 --- /dev/null +++ b/mmv1/products/dialogflowcx/TestCase.yaml @@ -0,0 +1,451 @@ +# 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: 'TestCase' +base_url: '{{parent}}/testCases' +update_verb: :PATCH +update_mask: true +description: | + You can use the built-in test feature to uncover bugs and prevent regressions. A test execution verifies that agent responses have not changed for end-user inputs defined in the test case. +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Official Documentation': 'https://cloud.google.com/dialogflow/cx/docs' + api: 'https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.testCases' +timeouts: !ruby/object:Api::Timeouts + insert_minutes: 40 + update_minutes: 40 +custom_code: !ruby/object:Provider::Terraform::CustomCode + pre_create: templates/terraform/pre_create/dialogflow_set_location.go.erb + pre_update: templates/terraform/pre_create/dialogflow_set_location.go.erb + pre_delete: templates/terraform/pre_create/dialogflow_set_location.go.erb + pre_read: templates/terraform/pre_create/dialogflow_set_location.go.erb +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'dialogflowcx_test_case_full' + primary_resource_id: 'basic_test_case' + vars: + agent_name: 'dialogflowcx-agent' +skip_sweeper: true +id_format: '{{parent}}/testCases/{{name}}' +import_format: ['{{%parent}}/testCases/{{name}}'] +parameters: + - !ruby/object:Api::Type::String + name: parent + url_param_only: true + immutable: true + description: | + The agent to create the test case for. + Format: projects//locations//agents/. +properties: + - !ruby/object:Api::Type::String + name: 'name' + output: true + description: | + The unique identifier of the test case. + Format: projects//locations//agents//testCases/. + custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb + - !ruby/object:Api::Type::Array + name: 'tags' + description: | + Tags are short descriptions that users may apply to test cases for organizational and filtering purposes. + Each tag should start with "#" and has a limit of 30 characters + item_type: Api::Type::String + - !ruby/object:Api::Type::String + name: 'displayName' + required: true + description: | + The human-readable name of the test case, unique within the agent. Limit of 200 characters. + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringLenBetween(0, 200)' + - !ruby/object:Api::Type::String + name: 'notes' + description: | + Additional freeform notes about the test case. Limit of 400 characters. + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringLenBetween(0, 400)' + - !ruby/object:Api::Type::NestedObject + name: 'testConfig' + description: | + Config for the test case. + properties: + - !ruby/object:Api::Type::Array + name: 'trackingParameters' + description: | + Session parameters to be compared when calculating differences. + item_type: Api::Type::String + - !ruby/object:Api::Type::String + name: 'flow' + description: | + Flow name to start the test case with. + Format: projects//locations//agents//flows/. + Only one of flow and page should be set to indicate the starting point of the test case. If neither is set, the test case will start with start page on the default start flow. + conflicts: + - test_config.0.page + - !ruby/object:Api::Type::String + name: 'page' + description: | + The page to start the test case with. + Format: projects//locations//agents//flows//pages/. + Only one of flow and page should be set to indicate the starting point of the test case. If neither is set, the test case will start with start page on the default start flow. + conflicts: + - test_config.0.flow + - !ruby/object:Api::Type::Array + name: 'testCaseConversationTurns' + description: | + The conversation turns uttered when the test case was created, in chronological order. These include the canonical set of agent utterances that should occur when the agent is working properly. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::NestedObject + name: 'userInput' + description: | + The user input. + properties: + - !ruby/object:Api::Type::NestedObject + name: 'input' + description: | + User input. Supports text input, event input, dtmf input in the test case. + properties: + # Does not support intent or audio as of this writing. https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/ConversationTurn#userinput + - !ruby/object:Api::Type::String + name: 'languageCode' + description: | + The language of the input. See [Language Support](https://cloud.google.com/dialogflow/cx/docs/reference/language) for a list of the currently supported language codes. + Note that queries in the same session do not necessarily need to specify the same language. + - !ruby/object:Api::Type::NestedObject + name: 'text' + description: | + The natural language text to be processed. + properties: + - !ruby/object:Api::Type::String + name: 'text' + required: true + description: | + The natural language text to be processed. Text length must not exceed 256 characters. + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringLenBetween(0, 256)' + - !ruby/object:Api::Type::NestedObject + name: 'event' + description: | + The event to be triggered. + properties: + - !ruby/object:Api::Type::String + name: 'event' + required: true + description: | + Name of the event. + - !ruby/object:Api::Type::NestedObject + name: 'dtmf' + description: | + The DTMF event to be handled. + properties: + - !ruby/object:Api::Type::String + name: 'digits' + description: | + The dtmf digits. + - !ruby/object:Api::Type::String + name: 'finishDigit' + description: | + The finish digit (if any). + # This can be an arbitrary json blob, so we use a string instead of a NestedObject. + - !ruby/object:Api::Type::String + name: 'injectedParameters' + description: | + Parameters that need to be injected into the conversation during intent detection. + custom_expand: 'templates/terraform/custom_expand/json_schema.erb' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb' + state_func: + 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); + return s }' + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringIsJSON' + - !ruby/object:Api::Type::Boolean + name: 'isWebhookEnabled' + description: | + If webhooks should be allowed to trigger in response to the user utterance. Often if parameters are injected, webhooks should not be enabled. + - !ruby/object:Api::Type::Boolean + name: 'enableSentimentAnalysis' + description: | + Whether sentiment analysis is enabled. + - !ruby/object:Api::Type::NestedObject + name: 'virtualAgentOutput' + description: | + The virtual agent output. + properties: + # This can be an arbitrary json blob, so we use a string instead of a NestedObject. + - !ruby/object:Api::Type::String + name: 'sessionParameters' + description: | + The session parameters available to the bot at this point. + custom_expand: 'templates/terraform/custom_expand/json_schema.erb' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb' + state_func: + 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); + return s }' + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringIsJSON' + - !ruby/object:Api::Type::NestedObject + name: 'triggeredIntent' + description: | + The [Intent](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.intents#Intent) that triggered the response. + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + The unique identifier of the intent. + Format: projects//locations//agents//intents/. + - !ruby/object:Api::Type::String + name: 'displayName' + # Output only because you can't set it independently of name; if they don't match, displayName is ignored and may lead to spurious changes + output: true + description: | + The human-readable name of the intent, unique within the agent. + - !ruby/object:Api::Type::NestedObject + name: 'currentPage' + description: | + The [Page](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.flows.pages#Page) on which the utterance was spoken. + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + The unique identifier of the page. + Format: projects//locations//agents//flows//pages/. + - !ruby/object:Api::Type::String + name: 'displayName' + # Output only because you can't set it independently of name; if they don't match, displayName is ignored and may lead to spurious changes + output: true + description: | + The human-readable name of the page, unique within the flow. + - !ruby/object:Api::Type::Array + name: 'textResponses' + description: | + The text responses from the agent for the turn. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Array + name: 'text' + description: | + A collection of text responses. + item_type: Api::Type::String + - !ruby/object:Api::Type::Time + name: 'creationTime' + description: 'When the test was created. A timestamp in RFC3339 text format.' + output: true + - !ruby/object:Api::Type::NestedObject + name: 'lastTestResult' + description: | + The latest test result. + output: true + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + The resource name for the test case result. + Format: projects//locations//agents//testCases//results/. + - !ruby/object:Api::Type::String + name: 'environment' + description: | + Environment where the test was run. If not set, it indicates the draft environment. + - !ruby/object:Api::Type::Array + name: 'conversationTurns' + description: | + The conversation turns uttered during the test case replay in chronological order. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::NestedObject + name: 'userInput' + description: | + The user input. + properties: + - !ruby/object:Api::Type::NestedObject + name: 'input' + description: | + User input. Supports text input, event input, dtmf input in the test case. + properties: + - !ruby/object:Api::Type::String + name: 'languageCode' + description: | + The language of the input. See [Language Support](https://cloud.google.com/dialogflow/cx/docs/reference/language) for a list of the currently supported language codes. + Note that queries in the same session do not necessarily need to specify the same language. + - !ruby/object:Api::Type::NestedObject + name: 'text' + description: | + The natural language text to be processed. + properties: + - !ruby/object:Api::Type::String + name: 'text' + required: true + description: | + The natural language text to be processed. Text length must not exceed 256 characters. + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringLenBetween(0, 256)' + - !ruby/object:Api::Type::NestedObject + name: 'event' + description: | + The event to be triggered. + properties: + - !ruby/object:Api::Type::String + name: 'event' + required: true + description: | + Name of the event. + - !ruby/object:Api::Type::NestedObject + name: 'dtmf' + description: | + The DTMF event to be handled. + properties: + - !ruby/object:Api::Type::String + name: 'digits' + description: | + The dtmf digits. + - !ruby/object:Api::Type::String + name: 'finishDigit' + description: | + The finish digit (if any). + # This can be an arbitrary json blob, so we use a string instead of a NestedObject. + - !ruby/object:Api::Type::String + name: 'injectedParameters' + description: | + Parameters that need to be injected into the conversation during intent detection. + custom_expand: 'templates/terraform/custom_expand/json_schema.erb' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb' + state_func: + 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); + return s }' + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringIsJSON' + - !ruby/object:Api::Type::Boolean + name: 'isWebhookEnabled' + description: | + If webhooks should be allowed to trigger in response to the user utterance. Often if parameters are injected, webhooks should not be enabled. + - !ruby/object:Api::Type::Boolean + name: 'enableSentimentAnalysis' + description: | + Whether sentiment analysis is enabled. + - !ruby/object:Api::Type::NestedObject + name: 'virtualAgentOutput' + description: | + The virtual agent output. + properties: + # This can be an arbitrary json blob, so we use a string instead of a NestedObject. + - !ruby/object:Api::Type::String + name: 'sessionParameters' + description: | + The session parameters available to the bot at this point. + custom_expand: 'templates/terraform/custom_expand/json_schema.erb' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb' + state_func: + 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); + return s }' + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringIsJSON' + - !ruby/object:Api::Type::Array + name: 'differences' + description: | + The list of differences between the original run and the replay for this output, if any. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Enum + name: 'type' + description: | + The type of diff. + * INTENT: The intent. + * PAGE: The page. + * PARAMETERS: The parameters. + * UTTERANCE: The message utterance. + * FLOW: The flow. + values: + - :INTENT + - :PAGE + - :PARAMETERS + - :UTTERANCE + - :FLOW + - !ruby/object:Api::Type::String + name: 'description' + description: | + A human readable description of the diff, showing the actual output vs expected output. + - !ruby/object:Api::Type::NestedObject + name: 'triggeredIntent' + description: | + The [Intent](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.intents#Intent) that triggered the response. + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + The unique identifier of the intent. + Format: projects//locations//agents//intents/. + - !ruby/object:Api::Type::String + name: 'displayName' + description: | + The human-readable name of the intent, unique within the agent. + - !ruby/object:Api::Type::NestedObject + name: 'currentPage' + description: | + The [Page](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.flows.pages#Page) on which the utterance was spoken. + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + The unique identifier of the page. + Format: projects//locations//agents//flows//pages/. + - !ruby/object:Api::Type::String + name: 'displayName' + description: | + The human-readable name of the page, unique within the flow. + - !ruby/object:Api::Type::Array + name: 'textResponses' + description: | + The text responses from the agent for the turn. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::Array + name: 'text' + description: | + A collection of text responses. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: 'status' + description: | + Response error from the agent in the test result. If set, other output is empty. + properties: + - !ruby/object:Api::Type::Integer + name: 'code' + description: | + The status code, which should be an enum value of google.rpc.Code. + - !ruby/object:Api::Type::String + name: 'message' + description: | + A developer-facing error message. + - !ruby/object:Api::Type::String + name: 'details' + description: | + A JSON encoded list of messages that carry the error details. + custom_expand: 'templates/terraform/custom_expand/json_value.erb' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb' + state_func: + 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); + return s }' + validation: !ruby/object:Provider::Terraform::Validation + function: 'validation.StringIsJSON' + - !ruby/object:Api::Type::Enum + name: 'testResult' + description: | + Whether the test case passed in the agent environment. + * PASSED: The test passed. + * FAILED: The test did not pass. + values: + - :PASSED + - :FAILED + - !ruby/object:Api::Type::Time + name: 'testTime' + description: 'The time that the test was run. A timestamp in RFC3339 text format.' diff --git a/mmv1/templates/terraform/examples/dialogflowcx_test_case_full.tf.erb b/mmv1/templates/terraform/examples/dialogflowcx_test_case_full.tf.erb new file mode 100644 index 000000000000..c399764f03f9 --- /dev/null +++ b/mmv1/templates/terraform/examples/dialogflowcx_test_case_full.tf.erb @@ -0,0 +1,125 @@ +resource "google_dialogflow_cx_agent" "agent" { + display_name = "<%= ctx[:vars]["agent_name"] %>" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr", "de", "es"] + time_zone = "America/New_York" + description = "Example description." + avatar_uri = "https://storage.cloud.google.com/dialogflow-test-host-image/cloud-logo.png" + enable_stackdriver_logging = true + enable_spell_correction = true + speech_to_text_settings { + enable_speech_adaptation = true + } +} + +resource "google_dialogflow_cx_page" "page" { + parent = google_dialogflow_cx_agent.agent.start_flow + display_name = "MyPage" + + transition_routes { + intent = google_dialogflow_cx_intent.intent.id + trigger_fulfillment { + messages { + text { + text = ["Training phrase response"] + } + } + } + } + + event_handlers { + event = "some-event" + trigger_fulfillment { + messages { + text { + text = ["Handling some event"] + } + } + } + } +} + +resource "google_dialogflow_cx_intent" "intent" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyIntent" + priority = 1 + training_phrases { + parts { + text = "training phrase" + } + repeat_count = 1 + } +} + +resource "google_dialogflow_cx_test_case" "<%= ctx[:primary_resource_id] %>" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyTestCase" + tags = ["#tag1"] + notes = "demonstrates a simple training phrase response" + + test_config { + tracking_parameters = ["some_param"] + page = google_dialogflow_cx_page.page.id + } + + test_case_conversation_turns { + user_input { + input { + language_code = "en" + text { + text = "training phrase" + } + } + injected_parameters = jsonencode({ some_param = "1" }) + is_webhook_enabled = true + enable_sentiment_analysis = true + } + virtual_agent_output { + session_parameters = jsonencode({ some_param = "1" }) + triggered_intent { + name = google_dialogflow_cx_intent.intent.id + } + current_page { + name = google_dialogflow_cx_page.page.id + } + text_responses { + text = ["Training phrase response"] + } + } + } + + test_case_conversation_turns { + user_input { + input { + event { + event = "some-event" + } + } + } + virtual_agent_output { + current_page { + name = google_dialogflow_cx_page.page.id + } + text_responses { + text = ["Handling some event"] + } + } + } + + test_case_conversation_turns { + user_input { + input { + dtmf { + digits = "12" + finish_digit = "3" + } + } + } + virtual_agent_output { + text_responses { + text = ["I didn't get that. Can you say it again?"] + } + } + } +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_test_case_test.go b/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_test_case_test.go new file mode 100644 index 000000000000..407bd10bf5b3 --- /dev/null +++ b/mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_test_case_test.go @@ -0,0 +1,255 @@ +package dialogflowcx_test + +import ( + "testing" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDialogflowCXTestCase_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), + Steps: []resource.TestStep{ + { + Config: testAccDialogflowCXTestCase_full(context), + }, + { + ResourceName: "google_dialogflow_cx_test_case.basic_test_case", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccDialogflowCXTestCase_update(context), + }, + { + ResourceName: "google_dialogflow_cx_test_case.basic_test_case", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccDialogflowCXTestCase_full(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_dialogflow_cx_agent" "agent" { + display_name = "tf-test-dialogflowcx-agent%{random_suffix}" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr", "de", "es"] + time_zone = "America/New_York" + description = "Example description." + avatar_uri = "https://storage.cloud.google.com/dialogflow-test-host-image/cloud-logo.png" + enable_stackdriver_logging = true + enable_spell_correction = true + speech_to_text_settings { + enable_speech_adaptation = true + } +} + +resource "google_dialogflow_cx_page" "page" { + parent = google_dialogflow_cx_agent.agent.start_flow + display_name = "MyPage" + + transition_routes { + intent = google_dialogflow_cx_intent.intent.id + trigger_fulfillment { + messages { + text { + text = ["Training phrase response"] + } + } + } + } + + event_handlers { + event = "some-event" + trigger_fulfillment { + messages { + text { + text = ["Handling some event"] + } + } + } + } +} + +resource "google_dialogflow_cx_intent" "intent" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyIntent" + priority = 1 + training_phrases { + parts { + text = "training phrase" + } + repeat_count = 1 + } +} + +resource "google_dialogflow_cx_test_case" "basic_test_case" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyTestCase" + + test_config { + tracking_parameters = [] + flow = google_dialogflow_cx_agent.agent.start_flow + } + + test_case_conversation_turns { + user_input { + input { + language_code = "en" + text { + text = "some phrase" + } + } + } + virtual_agent_output { + text_responses { + text = ["Some response"] + } + } + } +}`, context) +} + +func testAccDialogflowCXTestCase_update(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_dialogflow_cx_agent" "agent" { + display_name = "tf-test-dialogflowcx-agent%{random_suffix}" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr", "de", "es"] + time_zone = "America/New_York" + description = "Example description." + avatar_uri = "https://storage.cloud.google.com/dialogflow-test-host-image/cloud-logo.png" + enable_stackdriver_logging = true + enable_spell_correction = true + speech_to_text_settings { + enable_speech_adaptation = true + } +} + +resource "google_dialogflow_cx_page" "page" { + parent = google_dialogflow_cx_agent.agent.start_flow + display_name = "MyPage" + + transition_routes { + intent = google_dialogflow_cx_intent.intent.id + trigger_fulfillment { + messages { + text { + text = ["Training phrase response"] + } + } + } + } + + event_handlers { + event = "some-event" + trigger_fulfillment { + messages { + text { + text = ["Handling some event"] + } + } + } + } +} + +resource "google_dialogflow_cx_intent" "intent" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyIntent" + priority = 1 + training_phrases { + parts { + text = "training phrase" + } + repeat_count = 1 + } +} + +resource "google_dialogflow_cx_test_case" "basic_test_case" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyTestCase" + tags = ["#tag1"] + notes = "demonstrates a simple training phrase response" + + test_config { + tracking_parameters = ["some_param"] + page = google_dialogflow_cx_page.page.id + } + + test_case_conversation_turns { + user_input { + input { + language_code = "en" + text { + text = "training phrase" + } + } + injected_parameters = jsonencode({ some_param = "1" }) + is_webhook_enabled = true + enable_sentiment_analysis = true + } + virtual_agent_output { + session_parameters = jsonencode({ some_param = "1" }) + triggered_intent { + name = google_dialogflow_cx_intent.intent.id + } + current_page { + name = google_dialogflow_cx_page.page.id + } + text_responses { + text = ["Training phrase response"] + } + } + } + + test_case_conversation_turns { + user_input { + input { + event { + event = "some-event" + } + } + } + virtual_agent_output { + current_page { + name = google_dialogflow_cx_page.page.id + } + text_responses { + text = ["Handling some event"] + } + } + } + + test_case_conversation_turns { + user_input { + input { + dtmf { + digits = "12" + finish_digit = "3" + } + } + } + virtual_agent_output { + text_responses { + text = ["I didn't get that. Can you say it again?"] + } + } + } +}`, context) +} From 7e5d5d1a272a72b5cca3c80c26532be3f7846f83 Mon Sep 17 00:00:00 2001 From: Obada Alabbadi <76101898+obada-ab@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:36:16 +0200 Subject: [PATCH 043/476] Add BigQuery Table Constraints Field (#8885) * Add BigQuery Table Constraints Field * fix indentation for resource_bigquery_table_test --- .../bigquery/resource_bigquery_table.go | 290 ++++++++++++++++++ .../bigquery/resource_bigquery_table_test.go | 277 +++++++++++++++++ .../docs/r/bigquery_table.html.markdown | 48 +++ 3 files changed, 615 insertions(+) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index 4a2882021e48..f32333ec90b4 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -1069,6 +1069,119 @@ func ResourceBigQueryTable() *schema.Resource { Default: true, Description: `Whether or not to allow Terraform to destroy the instance. Unless this field is set to false in Terraform state, a terraform destroy or terraform apply that would delete the instance will fail.`, }, + + // TableConstraints: [Optional] Defines the primary key and foreign keys. + "table_constraints": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: `Defines the primary key and foreign keys.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + // PrimaryKey: [Optional] Represents the primary key constraint + // on a table's columns. Present only if the table has a primary key. + // The primary key is not enforced. + "primary_key": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: `Represents a primary key constraint on a table's columns. Present only if the table has a primary key. The primary key is not enforced.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + //Columns: [Required] The columns that are composed of the primary key constraint. + "columns": { + Type: schema.TypeList, + Required: true, + Description: `The columns that are composed of the primary key constraint.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + + // ForeignKeys: [Optional] Present only if the table has a foreign key. + // The foreign key is not enforced. + "foreign_keys": { + Type: schema.TypeList, + Optional: true, + Description: `Present only if the table has a foreign key. The foreign key is not enforced.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + // Name: [Optional] Set only if the foreign key constraint is named. + "name": { + Type: schema.TypeString, + Optional: true, + Description: `Set only if the foreign key constraint is named.`, + }, + + // ReferencedTable: [Required] The table that holds the primary key + // and is referenced by this foreign key. + "referenced_table": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Description: `The table that holds the primary key and is referenced by this foreign key.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + // ProjectId: [Required] The ID of the project containing this table. + "project_id": { + Type: schema.TypeString, + Required: true, + Description: `The ID of the project containing this table.`, + }, + + // DatasetId: [Required] The ID of the dataset containing this table. + "dataset_id": { + Type: schema.TypeString, + Required: true, + Description: `The ID of the dataset containing this table.`, + }, + + // TableId: [Required] The ID of the table. The ID must contain only + // letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum + // length is 1,024 characters. Certain operations allow suffixing of + // the table ID with a partition decorator, such as + // sample_table$20190123. + "table_id": { + Type: schema.TypeString, + Required: true, + Description: `The ID of the table. The ID must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum length is 1,024 characters. Certain operations allow suffixing of the table ID with a partition decorator, such as sample_table$20190123.`, + }, + }, + }, + }, + + // ColumnReferences: [Required] The pair of the foreign key column and primary key column. + "column_references": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Description: `The pair of the foreign key column and primary key column.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + // ReferencingColumn: [Required] The column that composes the foreign key. + "referencing_column": { + Type: schema.TypeString, + Required: true, + Description: `The column that composes the foreign key.`, + }, + + // ReferencedColumn: [Required] The column in the primary key that are + // referenced by the referencingColumn + "referenced_column": { + Type: schema.TypeString, + Required: true, + Description: `The column in the primary key that are referenced by the referencingColumn.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, UseJSONNumber: true, } @@ -1170,6 +1283,15 @@ func resourceTable(d *schema.ResourceData, meta interface{}) (*bigquery.Table, e } } + if v, ok := d.GetOk("table_constraints"); ok { + tableConstraints, err := expandTableConstraints(v) + if err != nil { + return nil, err + } + + table.TableConstraints = tableConstraints + } + return table, nil } @@ -1381,6 +1503,14 @@ func resourceBigQueryTableRead(d *schema.ResourceData, meta interface{}) error { } } + if res.TableConstraints != nil { + table_constraints := flattenTableConstraints(res.TableConstraints) + + if err := d.Set("table_constraints", table_constraints); err != nil { + return fmt.Errorf("Error setting table constraints: %s", err) + } + } + return nil } @@ -2007,6 +2137,166 @@ func flattenMaterializedView(mvd *bigquery.MaterializedViewDefinition) []map[str return []map[string]interface{}{result} } +func expandPrimaryKey(configured interface{}) *bigquery.TableConstraintsPrimaryKey { + if len(configured.([]interface{})) == 0 { + return nil + } + + raw := configured.([]interface{})[0].(map[string]interface{}) + pk := &bigquery.TableConstraintsPrimaryKey{} + + columns := []string{} + for _, rawColumn := range raw["columns"].([]interface{}) { + columns = append(columns, rawColumn.(string)) + } + if len(columns) > 0 { + pk.Columns = columns + } + + return pk +} + +func flattenPrimaryKey(edc *bigquery.TableConstraintsPrimaryKey) []map[string]interface{} { + result := map[string]interface{}{} + + if edc.Columns != nil { + result["columns"] = edc.Columns + } + + return []map[string]interface{}{result} +} + +func expandReferencedTable(configured interface{}) *bigquery.TableConstraintsForeignKeysReferencedTable { + raw := configured.([]interface{})[0].(map[string]interface{}) + rt := &bigquery.TableConstraintsForeignKeysReferencedTable{} + + if v, ok := raw["project_id"]; ok { + rt.ProjectId = v.(string) + } + if v, ok := raw["dataset_id"]; ok { + rt.DatasetId = v.(string) + } + if v, ok := raw["table_id"]; ok { + rt.TableId = v.(string) + } + + return rt +} + +func flattenReferencedTable(edc *bigquery.TableConstraintsForeignKeysReferencedTable) []map[string]interface{} { + result := map[string]interface{}{} + + result["project_id"] = edc.ProjectId + result["dataset_id"] = edc.DatasetId + result["table_id"] = edc.TableId + + return []map[string]interface{}{result} +} + +func expandColumnReference(configured interface{}) *bigquery.TableConstraintsForeignKeysColumnReferences { + raw := configured.(map[string]interface{}) + + cr := &bigquery.TableConstraintsForeignKeysColumnReferences{} + + if v, ok := raw["referencing_column"]; ok { + cr.ReferencingColumn = v.(string) + } + if v, ok := raw["referenced_column"]; ok { + cr.ReferencedColumn = v.(string) + } + + return cr +} + +func flattenColumnReferences(edc []*bigquery.TableConstraintsForeignKeysColumnReferences) []map[string]interface{} { + results := []map[string]interface{}{} + + for _, cr := range edc { + result := map[string]interface{}{} + result["referenced_column"] = cr.ReferencedColumn + result["referencing_column"] = cr.ReferencingColumn + results = append(results, result) + } + + return results +} + +func expandForeignKey(configured interface{}) *bigquery.TableConstraintsForeignKeys { + raw := configured.(map[string]interface{}) + + fk := &bigquery.TableConstraintsForeignKeys{} + if v, ok := raw["name"]; ok { + fk.Name = v.(string) + } + if v, ok := raw["referenced_table"]; ok { + fk.ReferencedTable = expandReferencedTable(v) + } + crs := []*bigquery.TableConstraintsForeignKeysColumnReferences{} + if v, ok := raw["column_references"]; ok { + for _, rawColumnReferences := range v.([]interface{}) { + crs = append(crs, expandColumnReference(rawColumnReferences)) + } + } + + if len(crs) > 0 { + fk.ColumnReferences = crs + } + + return fk +} + +func flattenForeignKeys(edc []*bigquery.TableConstraintsForeignKeys) []map[string]interface{} { + results := []map[string]interface{}{} + + for _, fr := range edc { + result := map[string]interface{}{} + result["name"] = fr.Name + result["column_references"] = flattenColumnReferences(fr.ColumnReferences) + result["referenced_table"] = flattenReferencedTable(fr.ReferencedTable) + results = append(results, result) + } + + return results +} + +func expandTableConstraints(cfg interface{}) (*bigquery.TableConstraints, error) { + raw := cfg.([]interface{})[0].(map[string]interface{}) + + edc := &bigquery.TableConstraints{} + + if v, ok := raw["primary_key"]; ok { + edc.PrimaryKey = expandPrimaryKey(v) + } + + fks := []*bigquery.TableConstraintsForeignKeys{} + + if v, ok := raw["foreign_keys"]; ok { + for _, rawForeignKey := range v.([]interface{}) { + fks = append(fks, expandForeignKey(rawForeignKey)) + } + } + + if len(fks) > 0 { + edc.ForeignKeys = fks + } + + return edc, nil + +} + +func flattenTableConstraints(edc *bigquery.TableConstraints) []map[string]interface{} { + result := map[string]interface{}{} + + if edc.PrimaryKey != nil { + result["primary_key"] = flattenPrimaryKey(edc.PrimaryKey) + } + if edc.ForeignKeys != nil { + result["foreign_keys"] = flattenForeignKeys(edc.ForeignKeys) + } + + return []map[string]interface{}{result} +} + func resourceBigQueryTableImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { config := meta.(*transport_tpg.Config) if err := tpgresource.ParseImportId([]string{ diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go index bed08d6020c9..8c6e63d11931 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go @@ -298,6 +298,93 @@ func TestAccBigQueryTable_RangePartitioning(t *testing.T) { }) } +func TestAccBigQueryTable_PrimaryKey(t *testing.T) { + t.Parallel() + resourceName := "google_bigquery_table.test" + datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTablePrimaryKey(datasetID, tableID), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + }, + }) +} + +func TestAccBigQueryTable_ForeignKey(t *testing.T) { + t.Parallel() + resourceName := "google_bigquery_table.test" + datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID_pk := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID_fk := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + + projectID := envvar.GetTestProjectFromEnv() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableForeignKeys(projectID, datasetID, tableID_pk, tableID_fk), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + }, + }) +} + +func TestAccBigQueryTable_updateTableConstraints(t *testing.T) { + t.Parallel() + resourceName := "google_bigquery_table.test" + datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID_pk := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID_fk := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + + projectID := envvar.GetTestProjectFromEnv() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableForeignKeys(projectID, datasetID, tableID_pk, tableID_fk), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + { + Config: testAccBigQueryTableTableConstraintsUpdate(projectID, datasetID, tableID_pk, tableID_fk), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection"}, + }, + }, + }) +} + func TestAccBigQueryTable_View(t *testing.T) { t.Parallel() @@ -3057,6 +3144,196 @@ resource "google_bigquery_table" "test" { `, datasetID, tableID) } +func testAccBigQueryTablePrimaryKey(datasetID, tableID string) string { + return fmt.Sprintf(` + resource "google_bigquery_dataset" "foo" { + dataset_id = "%s" + } + + resource "google_bigquery_table" "test" { + deletion_protection = false + table_id = "%s" + dataset_id = google_bigquery_dataset.foo.dataset_id + + table_constraints { + primary_key { + columns = ["id"] + } + } + + schema = <The `external_data_configuration` block supports: * `autodetect` - (Required) - Let BigQuery try to autodetect the schema @@ -366,6 +369,51 @@ in Terraform state, a `terraform destroy` or `terraform apply` that would delete `google_bigquery_default_service_account` datasource and the `google_kms_crypto_key_iam_binding` resource. +The `table_constraints` block supports: + +* `primary_key` - (Optional) Represents the primary key constraint + on a table's columns. Present only if the table has a primary key. + The primary key is not enforced. + Structure is [documented below](#nested_primary_key). + +* `foreign_keys` - (Optional) Present only if the table has a foreign key. + The foreign key is not enforced. + Structure is [documented below](#nested_foreign_keys). + +The `primary_key` block supports: + +* `columns`: (Required) The columns that are composed of the primary key constraint. + +The `foreign_keys` block supports: + +* `name`: (Optional) Set only if the foreign key constraint is named. + +* `referenced_table`: (Required) The table that holds the primary key + and is referenced by this foreign key. + Structure is [documented below](#nested_referenced_table). + +* `column_references`: (Required) The pair of the foreign key column and primary key column. + Structure is [documented below](#nested_column_references). + +The `referenced_table` block supports: + +* `project_id`: (Required) The ID of the project containing this table. + +* `dataset_id`: (Required) The ID of the dataset containing this table. + +* `table_id`: (Required) The ID of the table. The ID must contain only + letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum + length is 1,024 characters. Certain operations allow suffixing of + the table ID with a partition decorator, such as + sample_table$20190123. + +The `column_references` block supports: + +* `referencing_column`: (Required) The column that composes the foreign key. + +* `referenced_column`: (Required) The column in the primary key that are + referenced by the referencingColumn + ## Attributes Reference In addition to the arguments listed above, the following computed attributes are From af0d3928f86b48814457eb788859f9bdbd2fbb07 Mon Sep 17 00:00:00 2001 From: Sarah French <15078782+SarahFrench@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:47:37 +0100 Subject: [PATCH 044/476] Add tests around how plugin framework provider configuration code handles `batching` block (#8901) * Add WIP version of PF `batching` test * Update SDK `batching` tests: rename test cases, remove unused inputs, make it clear values are arbitary * Add PF test cases to match existing SDK test cases * Re-add inputs - used for checks after error * Add empty string test case * Add unknown values test cases * Fix test defect --- .../fwtransport/framework_config_test.go.erb | 160 ++++++++++++++++++ .../provider/provider_internal_test.go | 46 ++--- 2 files changed, 184 insertions(+), 22 deletions(-) diff --git a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb index b356c7728fd3..a92cfdc70f49 100644 --- a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb +++ b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb @@ -1509,3 +1509,163 @@ func TestFrameworkProvider_LoadAndValidateFramework_requestTimeout(t *testing.T) }) } } + +func TestFrameworkProvider_LoadAndValidateFramework_batching(t *testing.T) { + + // Note: In the test function we need to set the below fields in test case's fwmodels.ProviderModel value + // this is to stop the code under tests experiencing errors, and could be addressed in future refactoring. + // - Credentials: If we don't set this then the test looks for application default credentials and can fail depending on the machine running the test + // - ImpersonateServiceAccountDelegates: If we don't set this, we get a nil pointer exception ¯\_(ツ)_/¯ + + cases := map[string]struct { + // It's not easy to create the value of Batching in the test case, so these inputs are used in the test function + SetBatchingAsNull bool + SetBatchingAsUnknown bool + EnableBatchingValue basetypes.BoolValue + SendAfterValue basetypes.StringValue + + EnvVariables map[string]string + + ExpectBatchingNull bool + ExpectBatchingUnknown bool + ExpectEnableBatchingValue basetypes.BoolValue + ExpectSendAfterValue basetypes.StringValue + ExpectError bool + }{ + "batching can be configured with values for enable_batching and send_after": { + EnableBatchingValue: types.BoolValue(true), + SendAfterValue: types.StringValue("123s"), + ExpectEnableBatchingValue: types.BoolValue(true), + ExpectSendAfterValue: types.StringValue("123s"), + }, + "if batching is an empty block, it will set the default values for enable_batching and send_after": { + // In this test, we try to create a list containing only null values + EnableBatchingValue: types.BoolNull(), + SendAfterValue: types.StringNull(), + ExpectEnableBatchingValue: types.BoolValue(true), + ExpectSendAfterValue: types.StringValue("10s"), + }, + "when batching is configured with only enable_batching, send_after will be set to a default value": { + EnableBatchingValue: types.BoolValue(true), + SendAfterValue: types.StringNull(), + ExpectEnableBatchingValue: types.BoolValue(true), + ExpectSendAfterValue: types.StringValue("10s"), + }, + "when batching is configured with only send_after, enable_batching will be set to a default value": { + EnableBatchingValue: types.BoolNull(), + SendAfterValue: types.StringValue("123s"), + ExpectEnableBatchingValue: types.BoolValue(true), + ExpectSendAfterValue: types.StringValue("123s"), + }, + // Handling empty strings in config + // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 + // "when batching is configured with send_after as an empty string, send_after will be set to a default value": { + // EnableBatchingValue: types.BoolValue(true), + // SendAfterValue: types.StringValue(""), + // ExpectEnableBatchingValue: types.BoolValue(true), + // ExpectSendAfterValue: types.StringValue("10s"), + // }, + // Handling unknown values + // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 + // "when batching is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { + // SetBatchingAsUnknown: true, + // ExpectEnableBatchingValue: types.BoolValue(true), + // ExpectSendAfterValue: types.StringValue("10s"), + // }, + // "when batching is configured with send_after as an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { + // EnableBatchingValue: types.BoolValue(true), + // SendAfterValue: types.StringUnknown(), + // ExpectEnableBatchingValue: types.BoolValue(true), + // ExpectSendAfterValue: types.StringValue("10s"), + // }, + // "when batching is configured with enable_batching as an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { + // EnableBatchingValue: types.BoolNull(), + // SendAfterValue: types.StringValue("123s"), + // ExpectEnableBatchingValue: types.BoolValue(true), + // ExpectSendAfterValue: types.StringValue("123s"), + // }, + // Error states + "if batching is configured with send_after as an invalid value, there's an error": { + SendAfterValue: types.StringValue("invalid value"), + ExpectError: true, + }, + "if batching is configured with send_after as number value without seconds (s), there's an error": { + SendAfterValue: types.StringValue("123"), + ExpectError: true, + }, + } + + for tn, tc := range cases { + t.Run(tn, func(t *testing.T) { + + // Arrange + acctest.UnsetTestProviderConfigEnvs(t) + acctest.SetupTestEnvs(t, tc.EnvVariables) + + ctx := context.Background() + tfVersion := "foobar" + providerversion := "999" + diags := diag.Diagnostics{} + + data := fwmodels.ProviderModel{} + data.Credentials = types.StringValue(transport_tpg.TestFakeCredentialsPath) + impersonateServiceAccountDelegates, _ := types.ListValue(types.StringType, []attr.Value{}) // empty list + data.ImpersonateServiceAccountDelegates = impersonateServiceAccountDelegates + + // TODO(SarahFrench) - this code will change when batching is reworked + // See https://github.com/GoogleCloudPlatform/magic-modules/pull/7668 + if !tc.SetBatchingAsNull && !tc.SetBatchingAsUnknown { + b, _ := types.ObjectValue( + map[string]attr.Type{ + "enable_batching": types.BoolType, + "send_after": types.StringType, + }, + map[string]attr.Value{ + "enable_batching": tc.EnableBatchingValue, + "send_after": tc.SendAfterValue, + }, + ) + batching, _ := types.ListValue(types.ObjectType{}.WithAttributeTypes(fwmodels.ProviderBatchingAttributes), []attr.Value{b}) + data.Batching = batching + } + if tc.SetBatchingAsNull { + data.Batching = types.ListNull(types.ObjectType{}.WithAttributeTypes(fwmodels.ProviderBatchingAttributes)) + } + if tc.SetBatchingAsUnknown { + data.Batching = types.ListUnknown(types.ObjectType{}.WithAttributeTypes(fwmodels.ProviderBatchingAttributes)) + } + + p := fwtransport.FrameworkProviderConfig{} + + // Act + p.LoadAndValidateFramework(ctx, &data, tfVersion, &diags, providerversion) + + // Assert + if diags.HasError() && tc.ExpectError { + return + } + if diags.HasError() && !tc.ExpectError { + for i, err := range diags.Errors() { + num := i + 1 + t.Logf("unexpected error #%d : %s", num, err.Summary()) + } + t.Fatalf("did not expect error, but [%d] error(s) occurred", diags.ErrorsCount()) + } + // Checking mutation of the data model + if !data.Batching.IsNull() && tc.ExpectBatchingNull { + t.Fatalf("want batching in the `fwmodels.ProviderModel` struct to be null, but got the value `%s`", data.Batching.String()) + } + if !data.Batching.IsUnknown() && tc.ExpectBatchingUnknown { + t.Fatalf("want batching in the `fwmodels.ProviderModel` struct to be unknown, but got the value `%s`", data.Batching.String()) + } + var pbConfigs []fwmodels.ProviderBatching + _ = data.Batching.ElementsAs(ctx, &pbConfigs, true) + if !pbConfigs[0].EnableBatching.Equal(tc.ExpectEnableBatchingValue) { + t.Fatalf("want batching.enable_batching in the `fwmodels.ProviderModel` struct to be `%s`, but got the value `%s`", tc.ExpectEnableBatchingValue.String(), data.Batching.String()) + } + if !pbConfigs[0].SendAfter.Equal(tc.ExpectSendAfterValue) { + t.Fatalf("want batching.send_after in the `fwmodels.ProviderModel` struct to be `%s`, but got the value `%s`", tc.ExpectSendAfterValue.String(), data.Batching.String()) + } + }) + } +} diff --git a/mmv1/third_party/terraform/provider/provider_internal_test.go b/mmv1/third_party/terraform/provider/provider_internal_test.go index cfb8fc7254ae..37d652753cdc 100644 --- a/mmv1/third_party/terraform/provider/provider_internal_test.go +++ b/mmv1/third_party/terraform/provider/provider_internal_test.go @@ -1565,31 +1565,32 @@ func TestProvider_ProviderConfigure_batching(t *testing.T) { ExpectedEnableBatchingValue bool ExpectedSendAfterValue string }{ - "if batch is an empty block, it will set the default values": { - ConfigValues: map[string]interface{}{ - "credentials": transport_tpg.TestFakeCredentialsPath, - }, - // Although at the schema level it's shown that by default it's set to false, the actual default value - // is true and can be seen in the `ExpanderProviderBatchingConfig` struct - // https://github.com/GoogleCloudPlatform/magic-modules/blob/8cd4a506f0ac4db7b07a8cce914449d34df6f20b/mmv1/third_party/terraform/transport/config.go.erb#L504-L508 - ExpectedEnableBatchingValue: false, - ExpectedSendAfterValue: "", // uses "" value to be able to set the default value of 30s - ExpectFieldUnset: true, - }, - "if batch is configured with both enable_batching and send_after": { + "batching can be configured with values for enable_batching and send_after": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, "batching": []interface{}{ map[string]interface{}{ "enable_batching": true, - "send_after": "10s", + "send_after": "123s", }, }, }, ExpectedEnableBatchingValue: true, - ExpectedSendAfterValue: "10s", + ExpectedSendAfterValue: "123s", + }, + "if batching is an empty block, it will set the default values for enable_batching and send_after": { + ConfigValues: map[string]interface{}{ + "credentials": transport_tpg.TestFakeCredentialsPath, + // batching not set + }, + // Although at the schema level it's shown that by default it's set to false, the actual default value + // is true and can be seen in the `ExpanderProviderBatchingConfig` struct + // https://github.com/GoogleCloudPlatform/magic-modules/blob/8cd4a506f0ac4db7b07a8cce914449d34df6f20b/mmv1/third_party/terraform/transport/config.go.erb#L504-L508 + ExpectedEnableBatchingValue: false, + ExpectedSendAfterValue: "", // uses "" value to be able to set the default value of 30s + ExpectFieldUnset: true, }, - "if batch is configured with only enable_batching": { + "when batching is configured with only enable_batching, send_after will be set to a default value": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, "batching": []interface{}{ @@ -1601,19 +1602,20 @@ func TestProvider_ProviderConfigure_batching(t *testing.T) { ExpectedEnableBatchingValue: true, ExpectedSendAfterValue: "", }, - "if batch is configured with only send_after": { + "when batching is configured with only send_after, enable_batching will be set to a default value": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, "batching": []interface{}{ map[string]interface{}{ - "send_after": "10s", + "send_after": "123s", }, }, }, ExpectedEnableBatchingValue: false, - ExpectedSendAfterValue: "10s", + ExpectedSendAfterValue: "123s", }, - "if batch is configured with invalid value for send_after": { + // Error states + "if batching is configured with send_after as an invalid value, there's an error": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, "batching": []interface{}{ @@ -1625,7 +1627,7 @@ func TestProvider_ProviderConfigure_batching(t *testing.T) { ExpectedSendAfterValue: "invalid value", ExpectError: true, }, - "if batch is configured with value without seconds (s) for send_after": { + "if batching is configured with send_after as number value without seconds (s), there's an error": { ConfigValues: map[string]interface{}{ "credentials": transport_tpg.TestFakeCredentialsPath, "batching": []interface{}{ @@ -1674,10 +1676,10 @@ func TestProvider_ProviderConfigure_batching(t *testing.T) { if ok { val := v.(string) if val != tc.ExpectedSendAfterValue { - t.Fatalf("expected request_timeout value set in provider data to be %v, got %v", tc.ExpectedSendAfterValue, val) + t.Fatalf("expected send_after value set in provider data to be %v, got %v", tc.ExpectedSendAfterValue, val) } if tc.ExpectFieldUnset { - t.Fatalf("expected request_timeout value to not be set in provider data, got %s", val) + t.Fatalf("expected send_after value to not be set in provider data, got %s", val) } } // Return early in tests where errors expected From a5769519890da8ba70b437c6e244d8a1c6ed1274 Mon Sep 17 00:00:00 2001 From: abheda-crest <105624942+abheda-crest@users.noreply.github.com> Date: Tue, 12 Sep 2023 22:36:55 +0530 Subject: [PATCH 045/476] Added `deletion_policy` field in `google_secret_manager_secret_version` resource (#8922) * Added deletion_policy field in google_secret_manager_secret_version resource * added extra line at the end of secret_version custom import --- .../products/secretmanager/SecretVersion.yaml | 32 +++++++++++++++++++ .../custom_import/secret_version.go.erb | 7 +++- ...ret_version_deletion_policy_abandon.tf.erb | 18 +++++++++++ ...ret_version_deletion_policy_disable.tf.erb | 18 +++++++++++ .../secret_version_deletion_policy.go.erb | 24 ++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 mmv1/templates/terraform/examples/secret_version_deletion_policy_abandon.tf.erb create mode 100644 mmv1/templates/terraform/examples/secret_version_deletion_policy_disable.tf.erb create mode 100644 mmv1/templates/terraform/pre_delete/secret_version_deletion_policy.go.erb diff --git a/mmv1/products/secretmanager/SecretVersion.yaml b/mmv1/products/secretmanager/SecretVersion.yaml index c87d5858324b..c7218c98887b 100644 --- a/mmv1/products/secretmanager/SecretVersion.yaml +++ b/mmv1/products/secretmanager/SecretVersion.yaml @@ -29,6 +29,22 @@ examples: vars: secret_id: 'secret-version' data: 'secret-data' + - !ruby/object:Provider::Terraform::Examples + name: 'secret_version_deletion_policy_abandon' + primary_resource_id: 'secret-version-deletion-policy' + vars: + secret_id: 'secret-version' + data: 'secret-data' + ignore_read_extra: + - 'deletion_policy' + - !ruby/object:Provider::Terraform::Examples + name: 'secret_version_deletion_policy_disable' + primary_resource_id: 'secret-version-deletion-policy' + vars: + secret_id: 'secret-version' + data: 'secret-data' + ignore_read_extra: + - 'deletion_policy' import_format: ['projects/{{%project}}/secrets/{{%secret_id}}/versions/{{%version}}'] custom_code: !ruby/object:Provider::Terraform::CustomCode @@ -37,6 +53,22 @@ custom_code: !ruby/object:Provider::Terraform::CustomCode custom_import: templates/terraform/custom_import/secret_version.go.erb resource_definition: templates/terraform/resource_definition/secret_version.go.erb decoder: templates/terraform/decoders/treat_destroyed_state_as_gone.erb + pre_delete: templates/terraform/pre_delete/secret_version_deletion_policy.go.erb +virtual_fields: + - !ruby/object:Api::Type::Enum + name: 'deletion_policy' + description: | + The deletion policy for the secret version. Setting `ABANDON` allows the resource + to be abandoned rather than deleted. Setting `DISABLE` allows the resource to be + disabled rather than deleted. Default is `DELETE`. Possible values are: + * DELETE + * DISABLE + * ABANDON + values: + - :DELETE + - :DISABLE + - :ABANDON + default_value: :DELETE parameters: - !ruby/object:Api::Type::ResourceRef name: secret diff --git a/mmv1/templates/terraform/custom_import/secret_version.go.erb b/mmv1/templates/terraform/custom_import/secret_version.go.erb index a8ddb95a8692..01404f0fc19a 100644 --- a/mmv1/templates/terraform/custom_import/secret_version.go.erb +++ b/mmv1/templates/terraform/custom_import/secret_version.go.erb @@ -23,4 +23,9 @@ return nil, fmt.Errorf("Error setting version: %s", err) } - return []*schema.ResourceData{d}, nil \ No newline at end of file + // Explicitly set virtual fields to default values on import + if err := d.Set("deletion_policy", "DELETE"); err != nil { + return nil, fmt.Errorf("Error setting version: %s", err) + } + + return []*schema.ResourceData{d}, nil diff --git a/mmv1/templates/terraform/examples/secret_version_deletion_policy_abandon.tf.erb b/mmv1/templates/terraform/examples/secret_version_deletion_policy_abandon.tf.erb new file mode 100644 index 000000000000..d095cef163bc --- /dev/null +++ b/mmv1/templates/terraform/examples/secret_version_deletion_policy_abandon.tf.erb @@ -0,0 +1,18 @@ +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "<%= ctx[:vars]['secret_id'] %>" + + replication { + user_managed { + replicas { + location = "us-central1" + } + } + } +} + +resource "google_secret_manager_secret_version" "<%= ctx[:primary_resource_id] %>" { + secret = google_secret_manager_secret.secret-basic.id + + secret_data = "<%= ctx[:vars]['data'] %>" + deletion_policy = "ABANDON" +} diff --git a/mmv1/templates/terraform/examples/secret_version_deletion_policy_disable.tf.erb b/mmv1/templates/terraform/examples/secret_version_deletion_policy_disable.tf.erb new file mode 100644 index 000000000000..a5933f9fe85f --- /dev/null +++ b/mmv1/templates/terraform/examples/secret_version_deletion_policy_disable.tf.erb @@ -0,0 +1,18 @@ +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "<%= ctx[:vars]['secret_id'] %>" + + replication { + user_managed { + replicas { + location = "us-central1" + } + } + } +} + +resource "google_secret_manager_secret_version" "<%= ctx[:primary_resource_id] %>" { + secret = google_secret_manager_secret.secret-basic.id + + secret_data = "<%= ctx[:vars]['data'] %>" + deletion_policy = "DISABLE" +} diff --git a/mmv1/templates/terraform/pre_delete/secret_version_deletion_policy.go.erb b/mmv1/templates/terraform/pre_delete/secret_version_deletion_policy.go.erb new file mode 100644 index 000000000000..4e91b9d3e79f --- /dev/null +++ b/mmv1/templates/terraform/pre_delete/secret_version_deletion_policy.go.erb @@ -0,0 +1,24 @@ +<%- # the license inside this block applies to this file + # 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. +-%> +deletionPolicy := d.Get("deletion_policy"); + +if deletionPolicy == "ABANDON" { + return nil +} else if deletionPolicy == "DISABLE" { + url, err = tpgresource.ReplaceVars(d, config, "{{SecretManagerBasePath}}{{name}}:disable") + if err != nil { + return err + } +} From 1b1387657ce8593059b9faea4fbc525fdc0469d4 Mon Sep 17 00:00:00 2001 From: Thomas MacLean Date: Tue, 12 Sep 2023 13:57:27 -0400 Subject: [PATCH 046/476] Add storageinsights product and ReportConfig resource type. (#8799) --- .../storageinsights/ReportConfig.yaml | 158 ++++++++++++++++++ mmv1/products/storageinsights/product.yaml | 29 ++++ .../storage_insights_report_config.tf.erb | 48 ++++++ ...rce_storage_insights_report_config_test.go | 156 +++++++++++++++++ 4 files changed, 391 insertions(+) create mode 100644 mmv1/products/storageinsights/ReportConfig.yaml create mode 100644 mmv1/products/storageinsights/product.yaml create mode 100644 mmv1/templates/terraform/examples/storage_insights_report_config.tf.erb create mode 100644 mmv1/third_party/terraform/services/storageinsights/resource_storage_insights_report_config_test.go diff --git a/mmv1/products/storageinsights/ReportConfig.yaml b/mmv1/products/storageinsights/ReportConfig.yaml new file mode 100644 index 000000000000..e8bc5f36bca8 --- /dev/null +++ b/mmv1/products/storageinsights/ReportConfig.yaml @@ -0,0 +1,158 @@ +# 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: 'ReportConfig' +base_url: projects/{{project}}/locations/{{location}}/reportConfigs +create_url: projects/{{project}}/locations/{{location}}/reportConfigs +self_link: projects/{{project}}/locations/{{location}}/reportConfigs/{{name}} +update_verb: :PATCH +update_mask: true +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Official Documentation': 'https://cloud.google.com/storage/docs/insights/using-storage-insights' + api: 'https://cloud.google.com/storage/docs/json_api/v1/reportConfig' +description: | + Represents an inventory report configuration. +examples: + - !ruby/object:Provider::Terraform::Examples + name: "storage_insights_report_config" + primary_resource_id: "config" + vars: + bucket_name: "my-bucket" + config_path: "templates/terraform/examples/storage_insights_report_config.tf.erb" +parameters: + - !ruby/object:Api::Type::String + name: 'location' + description: | + The location of the ReportConfig. The source and destination buckets specified in the ReportConfig + must be in the same location. + immutable: true + required: true + url_param_only: true +properties: + - !ruby/object:Api::Type::String + name: 'name' + output: true + description: | + The UUID of the inventory report configuration. + custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb + - !ruby/object:Api::Type::NestedObject + name: 'frequencyOptions' + description: | + Options for configuring how inventory reports are generated. + properties: + - !ruby/object:Api::Type::Enum + name: 'frequency' + description: | + The frequency in which inventory reports are generated. Values are DAILY or WEEKLY. + required: true + values: + - :DAILY + - :WEEKLY + - !ruby/object:Api::Type::NestedObject + name: 'startDate' + description: | + The date to start generating inventory reports. For example, {"day": 15, "month": 8, "year": 2022}. + required: true + properties: + - !ruby/object:Api::Type::Integer + name: 'day' + description: 'The day of the month to start generating inventory reports.' + required: true + - !ruby/object:Api::Type::Integer + name: 'month' + description: 'The month to start generating inventory reports.' + required: true + - !ruby/object:Api::Type::Integer + name: 'year' + description: 'The year to start generating inventory reports' + required: true + - !ruby/object:Api::Type::NestedObject + name: 'endDate' + description: | + The date to stop generating inventory reports. For example, {"day": 15, "month": 9, "year": 2022}. + required: true + properties: + - !ruby/object:Api::Type::Integer + name: 'day' + description: 'The day of the month to stop generating inventory reports.' + required: true + - !ruby/object:Api::Type::Integer + name: 'month' + description: 'The month to stop generating inventory reports.' + required: true + - !ruby/object:Api::Type::Integer + name: 'year' + description: 'The year to stop generating inventory reports' + required: true + - !ruby/object:Api::Type::NestedObject + name: 'csvOptions' + description: | + Options for configuring the format of the inventory report CSV file. + required: true + properties: + - !ruby/object:Api::Type::String + name: 'recordSeparator' + description: | + The character used to separate the records in the inventory report CSV file. + - !ruby/object:Api::Type::String + name: 'delimiter' + description: | + The delimiter used to separate the fields in the inventory report CSV file. + - !ruby/object:Api::Type::Boolean + name: 'headerRequired' + description: | + The boolean that indicates whether or not headers are included in the inventory report CSV file. + - !ruby/object:Api::Type::NestedObject + name: 'objectMetadataReportOptions' + description: | + Options for including metadata in an inventory report. + update_mask_fields: + - 'objectMetadataReportOptions.metadataFields' + - 'objectMetadataReportOptions.storageDestinationOptions.bucket' + - 'objectMetadataReportOptions.storageDestinationOptions.destinationPath' + properties: + - !ruby/object:Api::Type::Array + name: 'metadataFields' + description: | + The metadata fields included in an inventory report. + required: true + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: 'storageFilters' + properties: + - !ruby/object:Api::Type::String + name: 'bucket' + description: | + The filter to use when specifying which bucket to generate inventory reports for. + immutable: true + - !ruby/object:Api::Type::NestedObject + name: 'storageDestinationOptions' + description: | + Options for where the inventory reports are stored. + required: true + properties: + - !ruby/object:Api::Type::String + name: 'bucket' + description: | + The destination bucket that stores the generated inventory reports. + required: true + - !ruby/object:Api::Type::String + name: 'destinationPath' + description: | + The path within the destination bucket to store generated inventory reports. + - !ruby/object:Api::Type::String + name: 'displayName' + description: | + The editable display name of the inventory report configuration. Has a limit of 256 characters. Can be empty. diff --git a/mmv1/products/storageinsights/product.yaml b/mmv1/products/storageinsights/product.yaml new file mode 100644 index 000000000000..7f7a0b22e93c --- /dev/null +++ b/mmv1/products/storageinsights/product.yaml @@ -0,0 +1,29 @@ +# Copyright 2022 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::Product +name: StorageInsights +display_name: Cloud Storage Insights +versions: + - !ruby/object:Api::Product::Version + name: ga + base_url: https://storageinsights.googleapis.com/v1/ +scopes: + - https://www.googleapis.com/auth/devstorage.full_control +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Storage + url: https://console.cloud.google.com/apis/library/storage-component.googleapis.com/ + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Storage Insights + url: https://console.cloud.google.com/apis/library/storageinsights.googleapis.com/ diff --git a/mmv1/templates/terraform/examples/storage_insights_report_config.tf.erb b/mmv1/templates/terraform/examples/storage_insights_report_config.tf.erb new file mode 100644 index 000000000000..fba9c9d3ee0b --- /dev/null +++ b/mmv1/templates/terraform/examples/storage_insights_report_config.tf.erb @@ -0,0 +1,48 @@ +data "google_project" "project" { +} + +resource "google_storage_insights_report_config" "<%= ctx[:primary_resource_id] %>" { + display_name = "Test Report Config" + location = "us-central1" + frequency_options { + frequency = "WEEKLY" + start_date { + day = 15 + month = 3 + year = 2050 + } + end_date { + day = 15 + month = 4 + year = 2050 + } + } + csv_options { + record_separator = "\n" + delimiter = "," + header_required = false + } + object_metadata_report_options { + metadata_fields = ["bucket", "name", "project"] + storage_filters { + bucket = google_storage_bucket.report_bucket.name + } + storage_destination_options { + bucket = google_storage_bucket.report_bucket.name + destination_path = "test-insights-reports" + } + } +} + +resource "google_storage_bucket" "report_bucket" { + name = "<%= ctx[:vars]['bucket_name'] %>" + location = "us-central1" + force_destroy = true + uniform_bucket_level_access = true +} + +resource "google_storage_bucket_iam_member" "admin" { + bucket = google_storage_bucket.report_bucket.name + role = "roles/storage.admin" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-storageinsights.iam.gserviceaccount.com" +} diff --git a/mmv1/third_party/terraform/services/storageinsights/resource_storage_insights_report_config_test.go b/mmv1/third_party/terraform/services/storageinsights/resource_storage_insights_report_config_test.go new file mode 100644 index 000000000000..16a2d727e84e --- /dev/null +++ b/mmv1/third_party/terraform/services/storageinsights/resource_storage_insights_report_config_test.go @@ -0,0 +1,156 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package storageinsights_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccStorageInsightsReportConfig_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccStorageInsightsReportConfig_full(context), + }, + { + ResourceName: "google_storage_insights_report_config.config", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location"}, + }, + { + Config: testAccStorageInsightsReportConfig_update(context), + }, + { + ResourceName: "google_storage_insights_report_config.config", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location"}, + }, + }, + }) +} + +func testAccStorageInsightsReportConfig_full(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { +} + +resource "google_storage_insights_report_config" "config" { + display_name = "Test Report Config" + location = "us-central1" + frequency_options { + frequency = "WEEKLY" + start_date { + day = 15 + month = 3 + year = 2050 + } + end_date { + day = 15 + month = 4 + year = 2050 + } + } + csv_options { + record_separator = "\n" + delimiter = "," + header_required = false + } + object_metadata_report_options { + metadata_fields = ["bucket", "name", "project"] + storage_filters { + bucket = google_storage_bucket.report_bucket.name + } + storage_destination_options { + bucket = google_storage_bucket.report_bucket.name + destination_path = "test-insights-reports" + } + } + depends_on = [ + google_storage_bucket_iam_member.admin, + ] +} + +resource "google_storage_bucket" "report_bucket" { + name = "tf-test-my-bucket%{random_suffix}" + location = "us-central1" + force_destroy = true + uniform_bucket_level_access = true +} + +resource "google_storage_bucket_iam_member" "admin" { + bucket = google_storage_bucket.report_bucket.name + role = "roles/storage.admin" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-storageinsights.iam.gserviceaccount.com" +} +`, context) +} + +func testAccStorageInsightsReportConfig_update(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { +} + +resource "google_storage_insights_report_config" "config" { + display_name = "Test Report Config Updated" + location = "us-central1" + frequency_options { + frequency = "DAILY" + start_date { + day = 14 + month = 3 + year = 2040 + } + end_date { + day = 14 + month = 4 + year = 2040 + } + } + csv_options { + record_separator = "\r\n" + delimiter = "." + header_required = true + } + object_metadata_report_options { + metadata_fields = ["bucket", "name", "project"] + storage_filters { + bucket = google_storage_bucket.report_bucket.name + } + storage_destination_options { + bucket = google_storage_bucket.report_bucket.name + destination_path = "test-insights-reports-updated" + } + } + depends_on = [ + google_storage_bucket_iam_member.admin, + ] +} + +resource "google_storage_bucket" "report_bucket" { + name = "tf-test-my-bucket%{random_suffix}" + location = "us-central1" + force_destroy = true + uniform_bucket_level_access = true +} + +resource "google_storage_bucket_iam_member" "admin" { + bucket = google_storage_bucket.report_bucket.name + role = "roles/storage.admin" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-storageinsights.iam.gserviceaccount.com" +} +`, context) +} From 1178f758411e4eb7bc97a447defc145757fd5681 Mon Sep 17 00:00:00 2001 From: Jingwen Zheng <43050247+cindyzhengjw@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:02:49 -0400 Subject: [PATCH 047/476] Node pool operations should retry if they encountered quota error. (#8828) --- .../resource_container_node_pool.go.erb | 56 +++++++++++++------ .../terraform/tpgresource/utils.go | 31 +++++----- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb index c286914102d5..211a8737b636 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb @@ -581,9 +581,11 @@ func resourceContainerNodePoolCreate(d *schema.ResourceData, meta interface{}) e operation, err = clusterNodePoolsCreateCall.Do() if err != nil { - if tpgresource.IsFailedPreconditionError(err) { + if tpgresource.IsFailedPreconditionError(err) || tpgresource.IsQuotaError(err) { // We get failed precondition errors if the cluster is updating // while we try to add the node pool. + // We get quota errors if there the number of running concurrent + // operations reaches the quota. return resource.RetryableError(err) } return resource.NonRetryableError(err) @@ -786,9 +788,11 @@ func resourceContainerNodePoolDelete(d *schema.ResourceData, meta interface{}) e operation, err = clusterNodePoolsDeleteCall.Do() if err != nil { - if tpgresource.IsFailedPreconditionError(err) { + if tpgresource.IsFailedPreconditionError(err) || tpgresource.IsQuotaError(err) { // We get failed precondition errors if the cluster is updating // while we try to delete the node pool. + // We get quota errors if there the number of running concurrent + // operations reaches the quota. return resource.RetryableError(err) } return resource.NonRetryableError(err) @@ -1343,7 +1347,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated autoscaling in Node Pool %s", d.Id()) @@ -1381,7 +1385,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } @@ -1435,7 +1439,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated tags for node pool %s", name) @@ -1472,7 +1476,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node } // Call update serially. - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } @@ -1510,7 +1514,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node } // Call update serially. - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } @@ -1542,7 +1546,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated image type in Node Pool %s", d.Id()) @@ -1576,7 +1580,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated workload_metadata_config for node pool %s", name) @@ -1609,7 +1613,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } @@ -1642,7 +1646,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } @@ -1673,7 +1677,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node nodePoolInfo.location, "updating GKE node pool size", userAgent, timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] GKE node pool %s size has been updated to %d", name, newSize) @@ -1708,7 +1712,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node nodePoolInfo.location, "updating GKE node pool management", userAgent, timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated management in Node Pool %s", name) @@ -1735,7 +1739,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node nodePoolInfo.project, nodePoolInfo.location, "updating GKE node pool version", userAgent, timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated version in Node Pool %s", name) @@ -1760,7 +1764,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node return ContainerOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location, "updating GKE node pool node locations", userAgent, timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated node locations in Node Pool %s", name) @@ -1840,7 +1844,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node // Wait until it's updated return ContainerOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location, "updating GKE node pool upgrade settings", userAgent, timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } log.Printf("[INFO] Updated upgrade settings in Node Pool %s", name) @@ -1871,7 +1875,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } @@ -1922,3 +1926,21 @@ func containerNodePoolAwaitRestingState(config *transport_tpg.Config, name, proj return state, err } + +// Retries an operation while the canonical error code is FAILED_PRECONDTION +// or RESOURCE_EXHAUSTED which indicates there is an incompatible operation +// already running on the cluster or there are the number of allowed +// concurrent operations running on the cluster. These errors can be safely +// retried until the incompatible operation completes, and the newly +// requested operation can begin. +func retryWhileIncompatibleOperation(timeout time.Duration, lockKey string, f func() error) error { + return resource.Retry(timeout, func() *resource.RetryError { + if err := transport_tpg.LockedCall(lockKey, f); err != nil { + if tpgresource.IsFailedPreconditionError(err) || tpgresource.IsQuotaError(err) { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) +} diff --git a/mmv1/third_party/terraform/tpgresource/utils.go b/mmv1/third_party/terraform/tpgresource/utils.go index 3722678026c7..389ca9a7f931 100644 --- a/mmv1/third_party/terraform/tpgresource/utils.go +++ b/mmv1/third_party/terraform/tpgresource/utils.go @@ -20,7 +20,6 @@ import ( "github.com/hashicorp/errwrap" fwDiags "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "google.golang.org/api/googleapi" @@ -126,6 +125,20 @@ func IsFailedPreconditionError(err error) bool { return false } +func IsQuotaError(err error) bool { + gerr, ok := errwrap.GetType(err, &googleapi.Error{}).(*googleapi.Error) + if !ok { + return false + } + if gerr == nil { + return false + } + if gerr.Code != 429 { + return false + } + return true +} + func IsConflictError(err error) bool { if e, ok := err.(*googleapi.Error); ok && (e.Code == 409 || e.Code == 412) { return true @@ -501,22 +514,6 @@ func CheckGoogleIamPolicy(value string) error { return nil } -// Retries an operation while the canonical error code is FAILED_PRECONDTION -// which indicates there is an incompatible operation already running on the -// cluster. This error can be safely retried until the incompatible operation -// completes, and the newly requested operation can begin. -func RetryWhileIncompatibleOperation(timeout time.Duration, lockKey string, f func() error) error { - return resource.Retry(timeout, func() *resource.RetryError { - if err := transport_tpg.LockedCall(lockKey, f); err != nil { - if IsFailedPreconditionError(err) { - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) -} - func FrameworkDiagsToSdkDiags(fwD fwDiags.Diagnostics) *diag.Diagnostics { var diags diag.Diagnostics for _, e := range fwD.Errors() { From 186abeec7cdaedce7dfb227ac4a14d1999b3fc3e Mon Sep 17 00:00:00 2001 From: Scott Suarez Date: Tue, 12 Sep 2023 11:17:58 -0700 Subject: [PATCH 048/476] Don't error out if dataflow api fails to return sdk pipeline options (#8902) --- .../dataflow/resource_dataflow_job.go.erb | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job.go.erb b/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job.go.erb index fc1c5594d916..233e807b62ec 100644 --- a/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job.go.erb +++ b/mmv1/third_party/terraform/services/dataflow/resource_dataflow_job.go.erb @@ -350,25 +350,27 @@ func resourceDataflowJobRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error setting kms_key_name: %s", err) } + // This map isn't provided on all responses. It's not clear why but we only want to set these fields + // if the API returns. Otherwise this execution will crash for the user. + // https://github.com/hashicorp/terraform-provider-google/issues/7449 sdkPipelineOptions, err := tpgresource.ConvertToMap(job.Environment.SdkPipelineOptions) - if err != nil { - return err - } - optionsMap := sdkPipelineOptions["options"].(map[string]interface{}) - if err := d.Set("template_gcs_path", optionsMap["templateLocation"]); err != nil { - return fmt.Errorf("Error setting template_gcs_path: %s", err) - } - if err := d.Set("temp_gcs_location", optionsMap["tempLocation"]); err != nil { - return fmt.Errorf("Error setting temp_gcs_location: %s", err) - } - if err := d.Set("machine_type", optionsMap["machineType"]); err != nil { - return fmt.Errorf("Error setting machine_type: %s", err) - } - if err := d.Set("network", optionsMap["network"]); err != nil { - return fmt.Errorf("Error setting network: %s", err) - } - if err := d.Set("service_account_email", optionsMap["serviceAccountEmail"]); err != nil { - return fmt.Errorf("Error setting service_account_email: %s", err) + if err == nil { + optionsMap := sdkPipelineOptions["options"].(map[string]interface{}) + if err := d.Set("template_gcs_path", optionsMap["templateLocation"]); err != nil { + return fmt.Errorf("Error setting template_gcs_path: %s", err) + } + if err := d.Set("temp_gcs_location", optionsMap["tempLocation"]); err != nil { + return fmt.Errorf("Error setting temp_gcs_location: %s", err) + } + if err := d.Set("machine_type", optionsMap["machineType"]); err != nil { + return fmt.Errorf("Error setting machine_type: %s", err) + } + if err := d.Set("network", optionsMap["network"]); err != nil { + return fmt.Errorf("Error setting network: %s", err) + } + if err := d.Set("service_account_email", optionsMap["serviceAccountEmail"]); err != nil { + return fmt.Errorf("Error setting service_account_email: %s", err) + } } if ok := shouldStopDataflowJobDeleteQuery(job.CurrentState, d.Get("skip_wait_on_job_termination").(bool)); ok { From e5139d7826280c3119d3c550d04c084869fe3b2a Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Tue, 12 Sep 2023 12:26:53 -0700 Subject: [PATCH 049/476] Support Binary Authorization. (#8915) --- mmv1/products/containerattached/Cluster.yaml | 14 ++++++++++++++ .../container_attached_cluster_full.tf.erb | 3 +++ .../pre_update/containerattached_update.go.erb | 5 ++++- ...ource_container_attached_cluster_update_test.go | 9 +++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mmv1/products/containerattached/Cluster.yaml b/mmv1/products/containerattached/Cluster.yaml index 3d64fa3485b5..082415d82aa0 100644 --- a/mmv1/products/containerattached/Cluster.yaml +++ b/mmv1/products/containerattached/Cluster.yaml @@ -313,3 +313,17 @@ properties: name: enabled description: | Enable Managed Collection. + - !ruby/object:Api::Type::NestedObject + name: binaryAuthorization + description: | + Binary Authorization configuration. + allow_empty_object: true + default_from_api: true + properties: + - !ruby/object:Api::Type::Enum + name: evaluationMode + description: | + Configure Binary Authorization evaluation mode. + values: + - :DISABLED + - :PROJECT_SINGLETON_POLICY_ENFORCE diff --git a/mmv1/templates/terraform/examples/container_attached_cluster_full.tf.erb b/mmv1/templates/terraform/examples/container_attached_cluster_full.tf.erb index 676937a176d4..09a593035331 100644 --- a/mmv1/templates/terraform/examples/container_attached_cluster_full.tf.erb +++ b/mmv1/templates/terraform/examples/container_attached_cluster_full.tf.erb @@ -36,4 +36,7 @@ resource "google_container_attached_cluster" "primary" { enabled = true } } + binary_authorization { + evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE" + } } diff --git a/mmv1/templates/terraform/pre_update/containerattached_update.go.erb b/mmv1/templates/terraform/pre_update/containerattached_update.go.erb index 9c7b10aefae8..6829140b837a 100644 --- a/mmv1/templates/terraform/pre_update/containerattached_update.go.erb +++ b/mmv1/templates/terraform/pre_update/containerattached_update.go.erb @@ -9,9 +9,12 @@ if d.HasChange("logging_config") { if d.HasChange("monitoring_config") { newUpdateMask = append(newUpdateMask, "monitoring_config.managed_prometheus_config.enabled") } +if d.HasChange("binary_authorization") { + newUpdateMask = append(newUpdateMask, "binary_authorization.evaluation_mode") +} // Pull out any other set fields from the generated mask. for _, mask := range updateMask { - if mask == "authorization" || mask == "loggingConfig" || mask == "monitoringConfig" { + if mask == "authorization" || mask == "loggingConfig" || mask == "monitoringConfig" || mask == "binaryAuthorization" { continue } newUpdateMask = append(newUpdateMask, mask) diff --git a/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go b/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go index 8df998cc8aab..2b87744d4318 100644 --- a/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go +++ b/mmv1/third_party/terraform/services/containerattached/resource_container_attached_cluster_update_test.go @@ -90,6 +90,9 @@ resource "google_container_attached_cluster" "primary" { enabled = true } } + binary_authorization { + evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE" + } } `, context) } @@ -128,6 +131,9 @@ resource "google_container_attached_cluster" "primary" { monitoring_config { managed_prometheus_config {} } + binary_authorization { + evaluation_mode = "DISABLED" + } lifecycle { prevent_destroy = true } @@ -171,6 +177,9 @@ resource "google_container_attached_cluster" "primary" { monitoring_config { managed_prometheus_config {} } + binary_authorization { + evaluation_mode = "DISABLED" + } } `, context) } From a7a5af4ec2074bafcac061742215f229eb669fa9 Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Tue, 12 Sep 2023 20:33:45 +0000 Subject: [PATCH 050/476] Add support for serial and cross-file tests (#8919) --- tools/missing-test-detector/reader.go | 137 +++++++++++++----- tools/missing-test-detector/reader_test.go | 86 ++++++++++- .../testdata/service/cross_file_1_test.go | 35 +++++ .../testdata/service/cross_file_2_test.go | 36 +++++ .../testdata/service/serial_resource_test.go | 64 ++++++++ 5 files changed, 317 insertions(+), 41 deletions(-) create mode 100644 tools/missing-test-detector/testdata/service/cross_file_1_test.go create mode 100644 tools/missing-test-detector/testdata/service/cross_file_2_test.go create mode 100644 tools/missing-test-detector/testdata/service/serial_resource_test.go diff --git a/tools/missing-test-detector/reader.go b/tools/missing-test-detector/reader.go index f3c9b0468694..c6c384f9c1e4 100644 --- a/tools/missing-test-detector/reader.go +++ b/tools/missing-test-detector/reader.go @@ -28,56 +28,66 @@ type Test struct { Steps []Step } -// Return a slice of tests as well as a map of file names to errors encountered. +func (t *Test) String() string { + return fmt.Sprintf("%s: %#v", t.Name, t.Steps) +} + +// Return a slice of tests as well as a map of file or test names to errors encountered. func readAllTests(servicesDir string) ([]*Test, map[string]error) { dirs, err := os.ReadDir(servicesDir) if err != nil { return nil, map[string]error{servicesDir: err} } allTests := make([]*Test, 0) - errs := make(map[string]error, 0) + allErrs := make(map[string]error) for _, dir := range dirs { servicePath := filepath.Join(servicesDir, dir.Name()) files, err := os.ReadDir(servicePath) if err != nil { return nil, map[string]error{servicePath: err} } + var testFileNames []string for _, file := range files { if strings.HasSuffix(file.Name(), "_test.go") { - filePath := filepath.Join(servicePath, file.Name()) - tests, err := readTestFile(filePath) - if err != nil { - errs[filePath] = err - } - allTests = append(allTests, tests...) + testFileNames = append(testFileNames, filepath.Join(servicePath, file.Name())) } } + serviceTests, serviceErrs := readTestFiles(testFileNames) + for fileName, err := range serviceErrs { + allErrs[fileName] = err + } + allTests = append(allTests, serviceTests...) } - if len(errs) > 0 { - return allTests, errs + if len(allErrs) > 0 { + return allTests, allErrs } return allTests, nil } -func readTestFile(filename string) ([]*Test, error) { - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, filename, nil, 0) - if err != nil { - return nil, err - } +// Read all the test files in a service directory together to capture cross-file function usage. +func readTestFiles(filenames []string) ([]*Test, map[string]error) { funcDecls := make(map[string]*ast.FuncDecl) // map of function names to function declarations varDecls := make(map[string]*ast.BasicLit) // map of variable names to value expressions - for _, decl := range f.Decls { - if funcDecl, ok := decl.(*ast.FuncDecl); ok { - // This is a function declaration. - funcDecls[funcDecl.Name.Name] = funcDecl - } else if genDecl, ok := decl.(*ast.GenDecl); ok { - // This is an import, constant, type, or variable declaration - for _, spec := range genDecl.Specs { - if valueSpec, ok := spec.(*ast.ValueSpec); ok { - if len(valueSpec.Values) > 0 { - if basicLit, ok := valueSpec.Values[0].(*ast.BasicLit); ok { - varDecls[valueSpec.Names[0].Name] = basicLit + errs := make(map[string]error) // map of file or test names to errors encountered parsing + fset := token.NewFileSet() + for _, filename := range filenames { + f, err := parser.ParseFile(fset, filename, nil, 0) + if err != nil { + errs[filename] = err + continue + } + for _, decl := range f.Decls { + if funcDecl, ok := decl.(*ast.FuncDecl); ok { + // This is a function declaration. + funcDecls[funcDecl.Name.Name] = funcDecl + } else if genDecl, ok := decl.(*ast.GenDecl); ok { + // This is an import, constant, type, or variable declaration + for _, spec := range genDecl.Specs { + if valueSpec, ok := spec.(*ast.ValueSpec); ok { + if len(valueSpec.Values) > 0 { + if basicLit, ok := valueSpec.Values[0].(*ast.BasicLit); ok { + varDecls[valueSpec.Names[0].Name] = basicLit + } } } } @@ -85,27 +95,26 @@ func readTestFile(filename string) ([]*Test, error) { } } tests := make([]*Test, 0) - errs := make([]error, 0) for name, funcDecl := range funcDecls { if strings.HasPrefix(name, "TestAcc") { - test, err := readTestFunc(funcDecl, funcDecls, varDecls) + funcTests, err := readTestFunc(funcDecl, funcDecls, varDecls) if err != nil { - errs = append(errs, err) - } - if test != nil { - test.Name = name - tests = append(tests, test) + errs[name] = err } + tests = append(tests, funcTests...) } } if len(errs) > 0 { - return tests, fmt.Errorf("errors encountered parsing test file: %v", errs) + return tests, errs } return tests, nil } -func readTestFunc(testFunc *ast.FuncDecl, funcDecls map[string]*ast.FuncDecl, varDecls map[string]*ast.BasicLit) (*Test, error) { +func readTestFunc(testFunc *ast.FuncDecl, funcDecls map[string]*ast.FuncDecl, varDecls map[string]*ast.BasicLit) ([]*Test, error) { // This is an exported test function. + var tests []*Test + var errs []error + vars := make(map[string]*ast.CompositeLit, len(testFunc.Body.List)) // map of variable names to composite literal values in function body for _, stmt := range testFunc.Body.List { if exprStmt, ok := stmt.(*ast.ExprStmt); ok { if callExpr, ok := exprStmt.X.(*ast.CallExpr); ok { @@ -113,12 +122,64 @@ func readTestFunc(testFunc *ast.FuncDecl, funcDecls map[string]*ast.FuncDecl, va ident, isIdent := callExpr.Fun.(*ast.Ident) selExpr, isSelExpr := callExpr.Fun.(*ast.SelectorExpr) if isIdent && ident.Name == "VcrTest" || isSelExpr && selExpr.Sel.Name == "VcrTest" { - return readVcrTestCall(callExpr, funcDecls, varDecls) + test, err := readVcrTestCall(callExpr, funcDecls, varDecls) + if err != nil { + errs = append(errs, err) + } + test.Name = testFunc.Name.Name + tests = append(tests, test) + } + } + } else if assignStmt, ok := stmt.(*ast.AssignStmt); ok { + if len(assignStmt.Lhs) == 1 && len(assignStmt.Rhs) == 1 { + // For now, only allow single assignment variables for serial test maps. + // e.g. testCases := map[string]func(t *testing.T) {... + if ident, ok := assignStmt.Lhs[0].(*ast.Ident); ok { + if rhsCompLit, ok := assignStmt.Rhs[0].(*ast.CompositeLit); ok { + vars[ident.Name] = rhsCompLit + } } } + } else if rangeStmt, ok := stmt.(*ast.RangeStmt); ok { + if ident, ok := rangeStmt.X.(*ast.Ident); ok { + if varCompLit, ok := vars[ident.Name]; ok { + serialTests, serialErrs := readSerialTestCompLit(varCompLit, funcDecls, varDecls) + errs = append(errs, serialErrs...) + tests = append(tests, serialTests...) + } + } + } + } + if len(errs) > 0 { + return tests, fmt.Errorf("errors reading test func %s: %v", testFunc.Name.Name, errs) + } + return tests, nil +} + +// Reads a composite literal which is either a slice or a map of serialized test functions. +func readSerialTestCompLit(varCompLit *ast.CompositeLit, funcDecls map[string]*ast.FuncDecl, varDecls map[string]*ast.BasicLit) ([]*Test, []error) { + var tests []*Test + var errs []error + for _, elt := range varCompLit.Elts { + if eltKeyValueExpr, ok := elt.(*ast.KeyValueExpr); ok { + eltTests, err := readSerialTestEltKeyValueExpr(eltKeyValueExpr, funcDecls, varDecls) + if err != nil { + errs = append(errs, err) + } + tests = append(tests, eltTests...) + } + } + return tests, errs +} + +func readSerialTestEltKeyValueExpr(eltKeyValueExpr *ast.KeyValueExpr, funcDecls map[string]*ast.FuncDecl, varDecls map[string]*ast.BasicLit) ([]*Test, error) { + if ident, ok := eltKeyValueExpr.Value.(*ast.Ident); ok { + if testFunc, ok := funcDecls[ident.Name]; ok { + return readTestFunc(testFunc, funcDecls, varDecls) } + return nil, fmt.Errorf("failed to find function with name %s", ident.Name) } - return nil, nil + return nil, fmt.Errorf("element key value expression with key %+v had non-ident value %+v", eltKeyValueExpr.Key, eltKeyValueExpr.Value) } func readVcrTestCall(vcrTestCall *ast.CallExpr, funcDecls map[string]*ast.FuncDecl, varDecls map[string]*ast.BasicLit) (*Test, error) { diff --git a/tools/missing-test-detector/reader_test.go b/tools/missing-test-detector/reader_test.go index 57bb5cceee3b..e42d3eff4137 100644 --- a/tools/missing-test-detector/reader_test.go +++ b/tools/missing-test-detector/reader_test.go @@ -13,11 +13,13 @@ func TestReadAllTests(t *testing.T) { for path, err := range errs { t.Logf("path: %s, err: %v", path, err) } + } else { + t.Log("no services directory provided, skipping TestReadAllTests") } } func TestReadCoveredResourceTestFile(t *testing.T) { - tests, err := readTestFile("testdata/service/covered_resource_test.go") + tests, err := readTestFiles([]string{"testdata/service/covered_resource_test.go"}) if err != nil { t.Fatalf("error reading covered resource test file: %v", err) } @@ -45,7 +47,7 @@ func TestReadCoveredResourceTestFile(t *testing.T) { } func TestReadConfigVariableTestFile(t *testing.T) { - tests, err := readTestFile("testdata/service/config_variable_test.go") + tests, err := readTestFiles([]string{"testdata/service/config_variable_test.go"}) if err != nil { t.Fatalf("error reading config variable test file: %v", err) } @@ -65,7 +67,7 @@ func TestReadConfigVariableTestFile(t *testing.T) { } func TestReadMultipleResourcesTestFile(t *testing.T) { - tests, err := readTestFile("testdata/service/multiple_resource_test.go") + tests, err := readTestFiles([]string{"testdata/service/multiple_resource_test.go"}) if err != nil { t.Fatalf("error reading multiple resources test file: %v", err) } @@ -97,3 +99,81 @@ func TestReadMultipleResourcesTestFile(t *testing.T) { t.Errorf("found unexpected test steps for multiple resources: %#v, expected %#v", tests[0].Steps, expectedSteps) } } + +func TestReadSerialResourceTestFile(t *testing.T) { + tests, err := readTestFiles([]string{"testdata/service/serial_resource_test.go"}) + if err != nil { + t.Fatalf("error reading serial resource test file: %v", err) + } + if len(tests) != 2 { + t.Fatalf("unexpected number of tests: %d, expected 2", len(tests)) + } + if expectedTests := []*Test{ + { + Name: "testAccSerialResource1", + Steps: []Step{ + { + "serial_resource": { + "resource": {"field_one": "\"value-one\""}, + }, + }, + }, + }, + { + Name: "testAccSerialResource2", + Steps: []Step{ + { + "serial_resource": { + "resource": { + "field_two": Resource{ + "field_three": "\"value-two\"", + }, + }, + }, + }, + }, + }, + }; !reflect.DeepEqual(tests, expectedTests) { + t.Errorf("found unexpected serialized tests: %v, expected %v", tests, expectedTests) + } + +} + +func TestReadCrossFileTests(t *testing.T) { + tests, err := readTestFiles([]string{"testdata/service/cross_file_1_test.go", "testdata/service/cross_file_2_test.go"}) + if err != nil { + t.Fatalf("error reading cross file tests: %v", err) + } + if len(tests) != 2 { + t.Fatalf("unexpected number of tests: %d, expected 2", len(tests)) + } + if expectedTests := []*Test{ + { + Name: "testAccCrossFile1", + Steps: []Step{ + { + "serial_resource": { + "resource": {"field_one": "\"value-one\""}, + }, + }, + }, + }, + { + Name: "testAccCrossFile2", + Steps: []Step{ + { + "serial_resource": { + "resource": { + "field_two": Resource{ + "field_three": "\"value-two\"", + }, + }, + }, + }, + }, + }, + }; !reflect.DeepEqual(tests, expectedTests) { + t.Errorf("found unexpected cross file tests: %v, expected %v", tests, expectedTests) + } + +} diff --git a/tools/missing-test-detector/testdata/service/cross_file_1_test.go b/tools/missing-test-detector/testdata/service/cross_file_1_test.go new file mode 100644 index 000000000000..b2844846f0e2 --- /dev/null +++ b/tools/missing-test-detector/testdata/service/cross_file_1_test.go @@ -0,0 +1,35 @@ +package service_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccCrossFile(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "test1": testAccCrossFile1, + "test2": testAccCrossFile2, + } + + for name, tc := range testCases { + // shadow the tc variable into scope so that when + // the loop continues, if t.Run hasn't executed tc(t) + // yet, we don't have a race condition + // see https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccCrossFile1(t *testing.T) { + VcrTest(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: testAccCrossFileConfig1(), + }, + }, + }) +} diff --git a/tools/missing-test-detector/testdata/service/cross_file_2_test.go b/tools/missing-test-detector/testdata/service/cross_file_2_test.go new file mode 100644 index 000000000000..06b8bea8793c --- /dev/null +++ b/tools/missing-test-detector/testdata/service/cross_file_2_test.go @@ -0,0 +1,36 @@ +package service_test + +import ( + "google/provider/new/google-beta/acctest" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func testAccCrossFile2(t *testing.T) { + VcrTest(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: testAccCrossFileConfig2(), + }, + }, + }) +} + +func testAccCrossFileConfig1() string { + return acctest.Nprintf(` +resource "serial_resource" "resource" { + field_one = "value-one" +} +`, context) +} + +func testAccCrossFileConfig2() string { + return acctest.Nprintf(` +resource "serial_resource" "resource" { + field_two { + field_three = "value-two" + } +} +`, context) +} diff --git a/tools/missing-test-detector/testdata/service/serial_resource_test.go b/tools/missing-test-detector/testdata/service/serial_resource_test.go new file mode 100644 index 000000000000..6704384e895a --- /dev/null +++ b/tools/missing-test-detector/testdata/service/serial_resource_test.go @@ -0,0 +1,64 @@ +package service_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" +) + +func TestAccSerialResource(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "test1": testAccSerialResource1, + "test2": testAccSerialResource2, + } + + for name, tc := range testCases { + // shadow the tc variable into scope so that when + // the loop continues, if t.Run hasn't executed tc(t) + // yet, we don't have a race condition + // see https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccSerialResource1(t *testing.T) { + VcrTest(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: testAccSerialResourceConfig1(), + }, + }, + }) +} + +func testAccSerialResource2(t *testing.T) { + VcrTest(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: testAccSerialResourceConfig2(), + }, + }, + }) +} + +func testAccSerialResourceConfig1() string { + return acctest.Nprintf(` +resource "serial_resource" "resource" { + field_one = "value-one" +} +`, context) +} + +func testAccSerialResourceConfig2() string { + return acctest.Nprintf(` +resource "serial_resource" "resource" { + field_two { + field_three = "value-two" + } +} +`, context) +} From e1ba36705704ec54f00d55e19d6745b107c0f076 Mon Sep 17 00:00:00 2001 From: Dennis Kugelmann Date: Tue, 12 Sep 2023 20:42:16 +0000 Subject: [PATCH 051/476] Firestore: Add missing fields to Firestore database (#8909) * Adjust Firestore database etag description * Adjust Firestore database create_time description * Add update_time field to Firestore database * Add uid field to Firestore database --- mmv1/products/firestore/Database.yaml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/mmv1/products/firestore/Database.yaml b/mmv1/products/firestore/Database.yaml index 70c6bb4b1200..dad854e2c647 100644 --- a/mmv1/products/firestore/Database.yaml +++ b/mmv1/products/firestore/Database.yaml @@ -170,14 +170,24 @@ properties: - !ruby/object:Api::Type::Fingerprint name: etag description: | - This checksum is computed by the server based on the value of other fields, + Output only. This checksum is computed by the server based on the value of other fields, and may be sent on update and delete requests to ensure the client has an up-to-date value before proceeding. output: true - !ruby/object:Api::Type::String name: create_time description: | - The timestamp at which this database was created. + Output only. The timestamp at which this database was created. + output: true + - !ruby/object:Api::Type::String + name: update_time + description: | + Output only. The timestamp at which this database was most recently updated. + output: true + - !ruby/object:Api::Type::String + name: uid + description: | + Output only. The system-generated UUID4 for this Database. output: true - !ruby/object:Api::Type::String name: versionRetentionPeriod From 99358dc8ef2388518d8cb550ab93869b389098ce Mon Sep 17 00:00:00 2001 From: Scott Suarez Date: Tue, 12 Sep 2023 14:35:07 -0700 Subject: [PATCH 052/476] migrate membership-checker to be extensible (#8708) --- .ci/gcb-community-checker.yml | 76 ++++++-- .ci/gcb-contributor-membership-checker.yml | 77 ++++++-- .ci/magician/cloudbuild/build_trigger.go | 46 +++++ .ci/magician/cloudbuild/community.go | 100 ++++++++++ .ci/magician/cloudbuild/constants.go | 4 + .ci/magician/cloudbuild/init.go | 14 ++ .ci/magician/cmd/community_checker.go | 106 +++++++++++ .ci/magician/cmd/community_checker_test.go | 74 ++++++++ .ci/magician/cmd/membership_checker.go | 176 ++++++++++++++++++ .ci/magician/cmd/membership_checker_test.go | 113 +++++++++++ .ci/magician/cmd/mock_cloudbuild_test.go | 20 ++ .ci/magician/cmd/mock_github_test.go | 56 ++++++ .ci/magician/cmd/root.go | 45 +++++ .../github/REVIEWER_ASSIGNMENT_COMMENT.md | 5 + .ci/magician/github/get.go | 71 +++++++ .ci/magician/github/init.go | 33 ++++ .ci/magician/github/membership.go | 98 ++++++++++ .ci/magician/github/membership_test.go | 23 +++ .ci/magician/github/reviewer_assignment.go | 52 ++++++ .../github/reviewer_assignment_test.go | 136 ++++++++++++++ .ci/magician/github/set.go | 96 ++++++++++ .ci/magician/go.mod | 30 +++ .ci/magician/go.sum | 143 ++++++++++++++ .ci/magician/main.go | 11 ++ .ci/magician/utility/utils.go | 48 +++++ .ci/magician/utility/utils_test.go | 49 +++++ .ci/scripts/go-plus/magician/exec.sh | 18 ++ .github/workflows/membership-checker.yml | 6 +- 28 files changed, 1695 insertions(+), 31 deletions(-) create mode 100644 .ci/magician/cloudbuild/build_trigger.go create mode 100644 .ci/magician/cloudbuild/community.go create mode 100644 .ci/magician/cloudbuild/constants.go create mode 100644 .ci/magician/cloudbuild/init.go create mode 100644 .ci/magician/cmd/community_checker.go create mode 100644 .ci/magician/cmd/community_checker_test.go create mode 100644 .ci/magician/cmd/membership_checker.go create mode 100644 .ci/magician/cmd/membership_checker_test.go create mode 100644 .ci/magician/cmd/mock_cloudbuild_test.go create mode 100644 .ci/magician/cmd/mock_github_test.go create mode 100644 .ci/magician/cmd/root.go create mode 100644 .ci/magician/github/REVIEWER_ASSIGNMENT_COMMENT.md create mode 100644 .ci/magician/github/get.go create mode 100644 .ci/magician/github/init.go create mode 100644 .ci/magician/github/membership.go create mode 100644 .ci/magician/github/membership_test.go create mode 100644 .ci/magician/github/reviewer_assignment.go create mode 100644 .ci/magician/github/reviewer_assignment_test.go create mode 100644 .ci/magician/github/set.go create mode 100644 .ci/magician/go.mod create mode 100644 .ci/magician/go.sum create mode 100644 .ci/magician/main.go create mode 100644 .ci/magician/utility/utils.go create mode 100644 .ci/magician/utility/utils_test.go create mode 100755 .ci/scripts/go-plus/magician/exec.sh diff --git a/.ci/gcb-community-checker.yml b/.ci/gcb-community-checker.yml index eaf3d6456b36..b7032b5c6148 100644 --- a/.ci/gcb-community-checker.yml +++ b/.ci/gcb-community-checker.yml @@ -1,17 +1,67 @@ --- steps: - - name: 'gcr.io/graphite-docker-images/membership-checker' - id: community-checker - secretEnv: ["GITHUB_TOKEN", "GENERATE_DIFFS_TRIGGER", "RAKE_TESTS_TRIGGER"] - timeout: 8000s - args: - - "needs_approval" - - $_PR_NUMBER - - $COMMIT_SHA - - $BRANCH_NAME - - $_HEAD_REPO_URL - - $_HEAD_BRANCH - - $_BASE_BRANCH + # The GCB / GH integration uses a shallow clone of the repo. We need to convert + # that to a full clone in order to work with it properly. + # https://cloud.google.com/source-repositories/docs/integrating-with-cloud-build#unshallowing_clones + - name: "gcr.io/cloud-builders/git" + args: + - fetch + - --unshallow + + # Configure git + - name: "gcr.io/cloud-builders/git" + args: + - config + - --global + - user.email + - magic-modules+differ@google.com + - name: "gcr.io/cloud-builders/git" + args: + - config + - --global + - user.name + - "Modular Magician Diff Process" + + # Fetch main (only if it's not already present) + - name: "gcr.io/cloud-builders/git" + args: + - fetch + - origin + - main + + # Display commit log for clarity + - name: "gcr.io/cloud-builders/git" + args: + - log + - "--oneline" + - "-n 10" + + # Find common ancestor commit and apply diff for the .ci folder + - name: "gcr.io/cloud-builders/git" + id: findMergeBase + entrypoint: "bash" + args: + - "-c" + - | + base_commit=$(git merge-base origin/main HEAD) + echo "Common ancestor commit: $base_commit" + git diff $base_commit origin/main -- .ci/ + git diff $base_commit origin/main -- .ci/ > /workspace/ci.diff + git apply /workspace/ci.diff --allow-empty + + - name: 'gcr.io/graphite-docker-images/go-plus' + entrypoint: '/workspace/.ci/scripts/go-plus/magician/exec.sh' + id: community-checker + secretEnv: ["GITHUB_TOKEN", "GENERATE_DIFFS_TRIGGER"] + timeout: 8000s + args: + - "community-checker" + - $_PR_NUMBER + - $COMMIT_SHA + - $BRANCH_NAME + - $_HEAD_REPO_URL + - $_HEAD_BRANCH + - $_BASE_BRANCH availableSecrets: secretManager: @@ -19,5 +69,3 @@ availableSecrets: env: GITHUB_TOKEN - versionName: projects/673497134629/secrets/ci-trigger-generate-diffs/versions/latest env: GENERATE_DIFFS_TRIGGER - - versionName: projects/673497134629/secrets/ci-trigger-rake-test/versions/latest - env: RAKE_TESTS_TRIGGER diff --git a/.ci/gcb-contributor-membership-checker.yml b/.ci/gcb-contributor-membership-checker.yml index a8ce69bb3371..d44ea5a4b4a2 100644 --- a/.ci/gcb-contributor-membership-checker.yml +++ b/.ci/gcb-contributor-membership-checker.yml @@ -1,17 +1,68 @@ --- steps: - - name: 'gcr.io/graphite-docker-images/membership-checker' - id: contributor-membership-checker - secretEnv: ["GITHUB_TOKEN", "GENERATE_DIFFS_TRIGGER", "RAKE_TESTS_TRIGGER", "COMMUNITY_CHECKER_TRIGGER"] - timeout: 8000s - args: - - "auto_run" - - $_PR_NUMBER - - $COMMIT_SHA - - $BRANCH_NAME - - $_HEAD_REPO_URL - - $_HEAD_BRANCH - - $_BASE_BRANCH + # The GCB / GH integration uses a shallow clone of the repo. We need to convert + # that to a full clone in order to work with it properly. + # https://cloud.google.com/source-repositories/docs/integrating-with-cloud-build#unshallowing_clones + - name: "gcr.io/cloud-builders/git" + args: + - fetch + - --unshallow + + # Configure git + - name: "gcr.io/cloud-builders/git" + args: + - config + - --global + - user.email + - magic-modules+differ@google.com + - name: "gcr.io/cloud-builders/git" + args: + - config + - --global + - user.name + - "Modular Magician Diff Process" + + # Fetch main (only if it's not already present) + - name: "gcr.io/cloud-builders/git" + args: + - fetch + - origin + - main + + # Display commit log for clarity + - name: "gcr.io/cloud-builders/git" + args: + - log + - "--oneline" + - "-n 10" + + # Find common ancestor commit and apply diff for the .ci folder + - name: "gcr.io/cloud-builders/git" + id: findMergeBase + entrypoint: "bash" + args: + - "-c" + - | + base_commit=$(git merge-base origin/main HEAD) + echo "Common ancestor commit: $base_commit" + git diff $base_commit origin/main -- .ci/ + git diff $base_commit origin/main -- .ci/ > /workspace/ci.diff + git apply /workspace/ci.diff --allow-empty + + - name: "gcr.io/graphite-docker-images/go-plus" + entrypoint: "/workspace/.ci/scripts/go-plus/magician/exec.sh" + id: contributor-membership-checker + secretEnv: + ["GITHUB_TOKEN", "GENERATE_DIFFS_TRIGGER", "COMMUNITY_CHECKER_TRIGGER"] + timeout: 8000s + args: + - "membership-checker" + - $_PR_NUMBER + - $COMMIT_SHA + - $BRANCH_NAME + - $_HEAD_REPO_URL + - $_HEAD_BRANCH + - $_BASE_BRANCH availableSecrets: secretManager: @@ -19,7 +70,5 @@ availableSecrets: env: GITHUB_TOKEN - versionName: projects/673497134629/secrets/ci-trigger-generate-diffs/versions/latest env: GENERATE_DIFFS_TRIGGER - - versionName: projects/673497134629/secrets/ci-trigger-rake-test/versions/latest - env: RAKE_TESTS_TRIGGER - versionName: projects/673497134629/secrets/ci-trigger-community-checker/versions/latest env: COMMUNITY_CHECKER_TRIGGER diff --git a/.ci/magician/cloudbuild/build_trigger.go b/.ci/magician/cloudbuild/build_trigger.go new file mode 100644 index 000000000000..04ecaf80c748 --- /dev/null +++ b/.ci/magician/cloudbuild/build_trigger.go @@ -0,0 +1,46 @@ +package cloudbuild + +import ( + "context" + "fmt" + "os" + + "google.golang.org/api/cloudbuild/v1" +) + +func (cb cloudBuild) TriggerMMPresubmitRuns(commitSha string, substitutions map[string]string) error { + presubmitTriggerId, ok := os.LookupEnv("GENERATE_DIFFS_TRIGGER") + if !ok { + return fmt.Errorf("did not provide GENERATE_DIFFS_TRIGGER environment variable") + } + + err := triggerCloudBuildRun(PROJECT_ID, presubmitTriggerId, REPO_NAME, commitSha, substitutions) + if err != nil { + return err + } + + return nil +} + +func triggerCloudBuildRun(projectId, triggerId, repoName, commitSha string, substitutions map[string]string) error { + ctx := context.Background() + c, err := cloudbuild.NewService(ctx) + if err != nil { + return fmt.Errorf("failed to create Cloud Build service client: %s", err) + } + + repoSource := &cloudbuild.RepoSource{ + ProjectId: projectId, + RepoName: repoName, + CommitSha: commitSha, + Substitutions: substitutions, + } + + _, err = c.Projects.Triggers.Run(projectId, triggerId, repoSource).Do() + if err != nil { + return fmt.Errorf("failed to create Cloud Build run: %s", err) + } + + fmt.Println("Started Cloud Build Run: ", triggerId) + return nil +} diff --git a/.ci/magician/cloudbuild/community.go b/.ci/magician/cloudbuild/community.go new file mode 100644 index 000000000000..ff7634b82d7d --- /dev/null +++ b/.ci/magician/cloudbuild/community.go @@ -0,0 +1,100 @@ +package cloudbuild + +import ( + "context" + "fmt" + "os" + + "google.golang.org/api/cloudbuild/v1" +) + +func (cb cloudBuild) ApproveCommunityChecker(prNumber, commitSha string) error { + buildId, err := getPendingBuildId(PROJECT_ID, commitSha) + if err != nil { + return err + } + + if buildId == "" { + return fmt.Errorf("Failed to find pending build for PR %s", prNumber) + } + + err = approveBuild(PROJECT_ID, buildId) + if err != nil { + return err + } + + return nil +} + +func (cb cloudBuild) GetAwaitingApprovalBuildLink(prNumber, commitSha string) (string, error) { + buildId, err := getPendingBuildId(PROJECT_ID, commitSha) + if err != nil { + return "", err + } + + if buildId == "" { + return "", fmt.Errorf("failed to find pending build for PR %s", prNumber) + } + + targetUrl := fmt.Sprintf("https://console.cloud.google.com/cloud-build/builds;region=global/%s?project=%s", buildId, PROJECT_ID) + + return targetUrl, nil +} + +func getPendingBuildId(projectId, commitSha string) (string, error) { + COMMUNITY_CHECKER_TRIGGER, ok := os.LookupEnv("COMMUNITY_CHECKER_TRIGGER") + if !ok { + return "", fmt.Errorf("Did not provide COMMUNITY_CHECKER_TRIGGER environment variable") + } + + ctx := context.Background() + + c, err := cloudbuild.NewService(ctx) + if err != nil { + return "", err + } + + filter := fmt.Sprintf("trigger_id=%s AND status=PENDING", COMMUNITY_CHECKER_TRIGGER) + // Builds will be sorted by createTime, descending order. + // 50 should be enough to include the one needs auto approval + pageSize := int64(50) + + builds, err := c.Projects.Builds.List(projectId).Filter(filter).PageSize(pageSize).Do() + if err != nil { + return "", err + } + + for _, build := range builds.Builds { + if build.Substitutions["COMMIT_SHA"] == commitSha { + return build.Id, nil + } + } + + return "", nil +} + +func approveBuild(projectId, buildId string) error { + ctx := context.Background() + + c, err := cloudbuild.NewService(ctx) + if err != nil { + return err + } + + name := fmt.Sprintf("projects/%s/builds/%s", projectId, buildId) + + approveBuildRequest := &cloudbuild.ApproveBuildRequest{ + ApprovalResult: &cloudbuild.ApprovalResult{ + Decision: "APPROVED", + }, + } + + _, err = c.Projects.Builds.Approve(name, approveBuildRequest).Do() + if err != nil { + return err + } + + fmt.Println("Auto approved build ", buildId) + + return nil +} diff --git a/.ci/magician/cloudbuild/constants.go b/.ci/magician/cloudbuild/constants.go new file mode 100644 index 000000000000..a64c5fce7c61 --- /dev/null +++ b/.ci/magician/cloudbuild/constants.go @@ -0,0 +1,4 @@ +package cloudbuild + +const PROJECT_ID = "graphite-docker-images" +const REPO_NAME = "magic-modules" diff --git a/.ci/magician/cloudbuild/init.go b/.ci/magician/cloudbuild/init.go new file mode 100644 index 000000000000..e2d29face5a2 --- /dev/null +++ b/.ci/magician/cloudbuild/init.go @@ -0,0 +1,14 @@ +package cloudbuild + +type cloudBuild bool + +type CloudBuild interface { + ApproveCommunityChecker(prNumber, commitSha string) error + GetAwaitingApprovalBuildLink(prNumber, commitSha string) (string, error) + TriggerMMPresubmitRuns(commitSha string, substitutions map[string]string) error +} + +func NewCloudBuildService() CloudBuild { + var x cloudBuild = true + return x +} diff --git a/.ci/magician/cmd/community_checker.go b/.ci/magician/cmd/community_checker.go new file mode 100644 index 000000000000..5ff13e4a6346 --- /dev/null +++ b/.ci/magician/cmd/community_checker.go @@ -0,0 +1,106 @@ +/* +Copyright © 2023 NAME HERE +*/ +package cmd + +import ( + "fmt" + "magician/cloudbuild" + "magician/github" + "os" + + "github.com/spf13/cobra" +) + +type ccGithub interface { + GetPullRequestAuthor(string) (string, error) + GetUserType(string) github.UserType + RemoveLabel(prNumber string, label string) error + PostBuildStatus(prNumber string, title string, state string, targetUrl string, commitSha string) error +} + +type ccCloudbuild interface { + TriggerMMPresubmitRuns(commitSha string, substitutions map[string]string) error +} + +// communityApprovalCmd represents the communityApproval command +var communityApprovalCmd = &cobra.Command{ + Use: "community-checker", + Short: "Run presubmit generate diffs for untrusted users and remove awaiting-approval label", + Long: `This command processes pull requests and performs various validations and actions based on the PR's metadata and author. + + The following PR details are expected as arguments: + 1. PR Number + 2. Commit SHA + 3. Branch Name + 4. Head Repo URL + 5. Head Branch + 6. Base Branch + + The command performs the following steps: + 1. Retrieve and print the provided pull request details. + 2. Get the author of the pull request and determine their user type. + 3. If the author is not a trusted user (neither a Core Contributor nor a Googler): + a. Trigger cloud builds with specific substitutions for the PR. + 4. For all pull requests, the 'awaiting-approval' label is removed. + `, + Run: func(cmd *cobra.Command, args []string) { + prNumber := args[0] + fmt.Println("PR Number: ", prNumber) + + commitSha := args[1] + fmt.Println("Commit SHA: ", commitSha) + + branchName := args[2] + fmt.Println("Branch Name: ", branchName) + + headRepoUrl := args[3] + fmt.Println("Head Repo URL: ", headRepoUrl) + + headBranch := args[4] + fmt.Println("Head Branch: ", headBranch) + + baseBranch := args[5] + fmt.Println("Base Branch: ", baseBranch) + + gh := github.NewGithubService() + cb := cloudbuild.NewCloudBuildService() + execCommunityChecker(prNumber, commitSha, branchName, headRepoUrl, headBranch, baseBranch, gh, cb) + }, +} + +func execCommunityChecker(prNumber, commitSha, branchName, headRepoUrl, headBranch, baseBranch string, gh ccGithub, cb ccCloudbuild) { + substitutions := map[string]string{ + "BRANCH_NAME": branchName, + "_PR_NUMBER": prNumber, + "_HEAD_REPO_URL": headRepoUrl, + "_HEAD_BRANCH": headBranch, + "_BASE_BRANCH": baseBranch, + } + + author, err := gh.GetPullRequestAuthor(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + authorUserType := gh.GetUserType(author) + trusted := authorUserType == github.CoreContributorUserType || authorUserType == github.GooglerUserType + + // only triggers build for untrusted users (because trusted users will be handled by membership-checker) + if !trusted { + err = cb.TriggerMMPresubmitRuns(commitSha, substitutions) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } + + // in community-checker job: + // remove awaiting-approval label from external contributor PRs + gh.RemoveLabel(prNumber, "awaiting-approval") +} + +func init() { + rootCmd.AddCommand(communityApprovalCmd) +} diff --git a/.ci/magician/cmd/community_checker_test.go b/.ci/magician/cmd/community_checker_test.go new file mode 100644 index 000000000000..603c5c66273b --- /dev/null +++ b/.ci/magician/cmd/community_checker_test.go @@ -0,0 +1,74 @@ +package cmd + +import ( + "magician/github" + "testing" +) + +func TestExecCommunityChecker_CoreContributorFlow(t *testing.T) { + gh := &mockGithub{ + author: "core_author", + userType: github.CoreContributorUserType, + calledMethods: make(map[string]bool), + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execCommunityChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if cb.calledMethods["TriggerMMPresubmitRuns"] { + t.Fatal("presubmit runs redundantly triggered for core contributor") + } + + if !gh.calledMethods["RemoveLabel"] { + t.Fatal("awaiting-approval label not removed for PR ") + } + +} + +func TestExecCommunityChecker_GooglerFlow(t *testing.T) { + gh := &mockGithub{ + author: "googler_author", + userType: github.GooglerUserType, + calledMethods: make(map[string]bool), + firstReviewer: "reviewer1", + previousReviewers: []string{github.GetRandomReviewer(), "reviewer3"}, + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execCommunityChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if cb.calledMethods["TriggerMMPresubmitRuns"] { + t.Fatal("presubmit runs redundantly triggered for googler") + } + + if !gh.calledMethods["RemoveLabel"] { + t.Fatal("awaiting-approval label not removed for PR ") + } +} + +func TestExecCommunityChecker_AmbiguousUserFlow(t *testing.T) { + gh := &mockGithub{ + author: "ambiguous_author", + userType: github.CommunityUserType, + calledMethods: make(map[string]bool), + firstReviewer: github.GetRandomReviewer(), + previousReviewers: []string{github.GetRandomReviewer(), "reviewer3"}, + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execCommunityChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if !cb.calledMethods["TriggerMMPresubmitRuns"] { + t.Fatal("presubmit runs not triggered for ambiguous user") + } + + if !gh.calledMethods["RemoveLabel"] { + t.Fatal("awaiting-approval label not removed for PR ") + } +} diff --git a/.ci/magician/cmd/membership_checker.go b/.ci/magician/cmd/membership_checker.go new file mode 100644 index 000000000000..f4222ac149c4 --- /dev/null +++ b/.ci/magician/cmd/membership_checker.go @@ -0,0 +1,176 @@ +/* +Copyright © 2023 NAME HERE +*/ +package cmd + +import ( + "fmt" + "magician/cloudbuild" + "magician/github" + "os" + + "github.com/spf13/cobra" +) + +type mcGithub interface { + GetPullRequestAuthor(string) (string, error) + GetUserType(string) github.UserType + GetPullRequestRequestedReviewer(string) (string, error) + GetPullRequestPreviousAssignedReviewers(string) ([]string, error) + RequestPullRequestReviewer(prNumber string, reviewer string) error + PostComment(prNumber string, comment string) error + AddLabel(prNumber string, label string) error + PostBuildStatus(prNumber string, title string, state string, targetUrl string, commitSha string) error +} + +type mcCloudbuild interface { + ApproveCommunityChecker(prNumber, commitSha string) error + GetAwaitingApprovalBuildLink(prNumber, commitSha string) (string, error) + TriggerMMPresubmitRuns(commitSha string, substitutions map[string]string) error +} + +// membershipCheckerCmd represents the membershipChecker command +var membershipCheckerCmd = &cobra.Command{ + Use: "membership-checker", + Short: "Assigns reviewers and manages pull request processing based on the author's trust level.", + Long: `This command conducts a series of validations and actions based on the details and authorship of a provided pull request. + + The command expects the following pull request details as arguments: + 1. PR Number + 2. Commit SHA + 3. Branch Name + 4. Head Repo URL + 5. Head Branch + 6. Base Branch + + It then performs the following operations: + 1. Extracts and displays the pull request details. + 2. Fetches the author of the pull request and determines their contribution type. + 3. If the author is not a core contributor: + a. Identifies the initially requested reviewer and those who previously reviewed this PR. + b. Determines and requests reviewers based on the above. + c. Posts comments tailored to the contribution type, the trust level of the contributor, and the primary reviewer. + 4. For trusted authors (Core Contributors and Googlers): + a. Triggers generate-diffs using the provided PR details. + b. Automatically approves the community-checker run. + 5. For external or untrusted contributors: + a. Adds the 'awaiting-approval' label. + b. Posts a link prompting approval for the build. + `, + Args: cobra.ExactArgs(6), + Run: func(cmd *cobra.Command, args []string) { + prNumber := args[0] + fmt.Println("PR Number: ", prNumber) + + commitSha := args[1] + fmt.Println("Commit SHA: ", commitSha) + + branchName := args[2] + fmt.Println("Branch Name: ", branchName) + + headRepoUrl := args[3] + fmt.Println("Head Repo URL: ", headRepoUrl) + + headBranch := args[4] + fmt.Println("Head Branch: ", headBranch) + + baseBranch := args[5] + fmt.Println("Base Branch: ", baseBranch) + + gh := github.NewGithubService() + cb := cloudbuild.NewCloudBuildService() + execMembershipChecker(prNumber, commitSha, branchName, headRepoUrl, headBranch, baseBranch, gh, cb) + }, +} + +func execMembershipChecker(prNumber, commitSha, branchName, headRepoUrl, headBranch, baseBranch string, gh mcGithub, cb mcCloudbuild) { + substitutions := map[string]string{ + "BRANCH_NAME": branchName, + "_PR_NUMBER": prNumber, + "_HEAD_REPO_URL": headRepoUrl, + "_HEAD_BRANCH": headBranch, + "_BASE_BRANCH": baseBranch, + } + + author, err := gh.GetPullRequestAuthor(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + authorUserType := gh.GetUserType(author) + trusted := authorUserType == github.CoreContributorUserType || authorUserType == github.GooglerUserType + + if authorUserType != github.CoreContributorUserType { + fmt.Println("Not core contributor - assigning reviewer") + + firstRequestedReviewer, err := gh.GetPullRequestRequestedReviewer(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + previouslyInvolvedReviewers, err := gh.GetPullRequestPreviousAssignedReviewers(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + reviewersToRequest, newPrimaryReviewer := github.ChooseReviewers(firstRequestedReviewer, previouslyInvolvedReviewers) + + for _, reviewer := range reviewersToRequest { + err = gh.RequestPullRequestReviewer(prNumber, reviewer) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } + + if newPrimaryReviewer != "" { + comment := github.FormatReviewerComment(newPrimaryReviewer, authorUserType, trusted) + err = gh.PostComment(prNumber, comment) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } + } + + // auto_run(contributor-membership-checker) will be run on every commit or /gcbrun: + // only triggers builds for trusted users + if trusted { + err = cb.TriggerMMPresubmitRuns(commitSha, substitutions) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } + + // in contributor-membership-checker job: + // 1. auto approve community-checker run for trusted users + // 2. add awaiting-approval label to external contributor PRs + if trusted { + err = cb.ApproveCommunityChecker(prNumber, commitSha) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } else { + gh.AddLabel(prNumber, "awaiting-approval") + targetUrl, err := cb.GetAwaitingApprovalBuildLink(prNumber, commitSha) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + err = gh.PostBuildStatus(prNumber, "Approve Build", "success", targetUrl, commitSha) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } +} + +func init() { + rootCmd.AddCommand(membershipCheckerCmd) +} diff --git a/.ci/magician/cmd/membership_checker_test.go b/.ci/magician/cmd/membership_checker_test.go new file mode 100644 index 000000000000..6ede73e333b4 --- /dev/null +++ b/.ci/magician/cmd/membership_checker_test.go @@ -0,0 +1,113 @@ +package cmd + +import ( + "magician/github" + "testing" +) + +func TestExecMembershipChecker_CoreContributorFlow(t *testing.T) { + gh := &mockGithub{ + author: "core_author", + userType: github.CoreContributorUserType, + calledMethods: make(map[string]bool), + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execMembershipChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if gh.calledMethods["RequestPullRequestReviewer"] { + t.Fatal("Incorrectly requested review for core contributor") + } + + if !cb.calledMethods["TriggerMMPresubmitRuns"] { + t.Fatal("presubmit runs not triggered for core author") + } + + if !cb.calledMethods["ApproveCommunityChecker"] { + t.Fatal("community checker not approved for core author") + } + +} + +func TestExecMembershipChecker_GooglerFlow(t *testing.T) { + gh := &mockGithub{ + author: "googler_author", + userType: github.GooglerUserType, + calledMethods: make(map[string]bool), + firstReviewer: "reviewer1", + previousReviewers: []string{github.GetRandomReviewer(), "reviewer3"}, + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execMembershipChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if !gh.calledMethods["RequestPullRequestReviewer"] { + t.Fatal("Review wasn't requested for googler") + } + + if !cb.calledMethods["TriggerMMPresubmitRuns"] { + t.Fatal("Presubmit runs not triggered for googler") + } + + if !cb.calledMethods["ApproveCommunityChecker"] { + t.Fatal("Community checker not approved for googler") + } +} + +func TestExecMembershipChecker_AmbiguousUserFlow(t *testing.T) { + gh := &mockGithub{ + author: "ambiguous_author", + userType: github.CommunityUserType, + calledMethods: make(map[string]bool), + firstReviewer: github.GetRandomReviewer(), + previousReviewers: []string{github.GetRandomReviewer(), "reviewer3"}, + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execMembershipChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if !gh.calledMethods["RequestPullRequestReviewer"] { + t.Fatal("Review wasn't requested for ambiguous user") + } + + if !gh.calledMethods["AddLabel"] || !cb.calledMethods["GetAwaitingApprovalBuildLink"] { + t.Fatal("Label wasn't posted to pull request") + } + + if cb.calledMethods["ApproveCommunityChecker"] { + t.Fatal("Incorrectly approved community checker for ambiguous user") + } + + if cb.calledMethods["TriggerMMPresubmitRuns"] { + t.Fatal("Incorrectly triggered presubmit runs for ambiguous user") + } +} + +func TestExecMembershipChecker_CommentForNewPrimaryReviewer(t *testing.T) { + gh := &mockGithub{ + author: "googler_author", + userType: github.GooglerUserType, + calledMethods: make(map[string]bool), + firstReviewer: "", + previousReviewers: []string{"reviewer3"}, + } + cb := &mockCloudBuild{ + calledMethods: make(map[string]bool), + } + + execMembershipChecker("pr1", "sha1", "branch1", "url1", "head1", "base1", gh, cb) + + if !gh.calledMethods["PostComment"] { + t.Fatal("Review wasn't requested for googler") + } + + if !gh.calledMethods["PostComment"] { + t.Fatal("Comment wasn't posted stating user status") + } +} diff --git a/.ci/magician/cmd/mock_cloudbuild_test.go b/.ci/magician/cmd/mock_cloudbuild_test.go new file mode 100644 index 000000000000..e88b949ad846 --- /dev/null +++ b/.ci/magician/cmd/mock_cloudbuild_test.go @@ -0,0 +1,20 @@ +package cmd + +type mockCloudBuild struct { + calledMethods map[string]bool +} + +func (m *mockCloudBuild) ApproveCommunityChecker(prNumber, commitSha string) error { + m.calledMethods["ApproveCommunityChecker"] = true + return nil +} + +func (m *mockCloudBuild) GetAwaitingApprovalBuildLink(prNumber, commitSha string) (string, error) { + m.calledMethods["GetAwaitingApprovalBuildLink"] = true + return "mocked_url", nil +} + +func (m *mockCloudBuild) TriggerMMPresubmitRuns(commitSha string, substitutions map[string]string) error { + m.calledMethods["TriggerMMPresubmitRuns"] = true + return nil +} diff --git a/.ci/magician/cmd/mock_github_test.go b/.ci/magician/cmd/mock_github_test.go new file mode 100644 index 000000000000..4f747b6645ce --- /dev/null +++ b/.ci/magician/cmd/mock_github_test.go @@ -0,0 +1,56 @@ +package cmd + +import "magician/github" + +type mockGithub struct { + author string + userType github.UserType + firstReviewer string + previousReviewers []string + calledMethods map[string]bool +} + +func (m *mockGithub) GetPullRequestAuthor(string) (string, error) { + m.calledMethods["GetPullRequestAuthor"] = true + return m.author, nil +} + +func (m *mockGithub) GetUserType(string) github.UserType { + m.calledMethods["GetUserType"] = true + return m.userType +} + +func (m *mockGithub) GetPullRequestRequestedReviewer(string) (string, error) { + m.calledMethods["GetPullRequestRequestedReviewer"] = true + return m.firstReviewer, nil +} + +func (m *mockGithub) GetPullRequestPreviousAssignedReviewers(string) ([]string, error) { + m.calledMethods["GetPullRequestPreviousAssignedReviewers"] = true + return m.previousReviewers, nil +} + +func (m *mockGithub) RequestPullRequestReviewer(prNumber string, reviewer string) error { + m.calledMethods["RequestPullRequestReviewer"] = true + return nil +} + +func (m *mockGithub) PostComment(prNumber string, comment string) error { + m.calledMethods["PostComment"] = true + return nil +} + +func (m *mockGithub) AddLabel(prNumber string, label string) error { + m.calledMethods["AddLabel"] = true + return nil +} + +func (m *mockGithub) RemoveLabel(prNumber string, label string) error { + m.calledMethods["RemoveLabel"] = true + return nil +} + +func (m *mockGithub) PostBuildStatus(prNumber string, title string, state string, targetUrl string, commitSha string) error { + m.calledMethods["PostBuildStatus"] = true + return nil +} diff --git a/.ci/magician/cmd/root.go b/.ci/magician/cmd/root.go new file mode 100644 index 000000000000..b19c57e6ea24 --- /dev/null +++ b/.ci/magician/cmd/root.go @@ -0,0 +1,45 @@ +/* +Copyright © 2023 NAME HERE +*/ +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +// rootCmd represents the base command when called without any subcommands + +var rootCmd = &cobra.Command{ + Use: "magician", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args) + }, + Short: "A brief description of your application", + Long: `A longer description that spans multiple lines and likely contains +examples and usage of using your application. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/.ci/magician/github/REVIEWER_ASSIGNMENT_COMMENT.md b/.ci/magician/github/REVIEWER_ASSIGNMENT_COMMENT.md new file mode 100644 index 000000000000..09d5bfc62936 --- /dev/null +++ b/.ci/magician/github/REVIEWER_ASSIGNMENT_COMMENT.md @@ -0,0 +1,5 @@ +Hello! I am a robot. It looks like you are a: {{if eq .authorUserType "Community Contributor"}}Community Contributor{{else}}~Community Contributor~{{end}} {{if eq .authorUserType "Googler"}}Googler{{else}}~Googler~{{end}} {{if eq .authorUserType "Core Contributor"}}Core Contributor{{else}}~Core Contributor~{{end}}. {{if .trusted}}Tests will run automatically.{{else}}Tests will require approval to run.{{end}} + +@{{.reviewer}}, a repository maintainer, has been assigned to review your changes. If you have not received review feedback within 2 business days, please leave a comment on this PR asking them to take a look. + +You can help make sure that review is quick by [doing a self-review](https://googlecloudplatform.github.io/magic-modules/contribute/review-pr/) and by [running impacted tests locally](https://googlecloudplatform.github.io/magic-modules/get-started/run-provider-tests/). \ No newline at end of file diff --git a/.ci/magician/github/get.go b/.ci/magician/github/get.go new file mode 100644 index 000000000000..cba19e5d773a --- /dev/null +++ b/.ci/magician/github/get.go @@ -0,0 +1,71 @@ +package github + +import ( + "fmt" + utils "magician/utility" +) + +func (gh *github) GetPullRequestAuthor(prNumber string) (string, error) { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/%s", prNumber) + + var pullRequest struct { + User struct { + Login string `json:"login"` + } `json:"user"` + } + + _, err := utils.RequestCall(url, "GET", gh.token, &pullRequest, nil) + if err != nil { + return "", err + } + + return pullRequest.User.Login, nil +} + +func (gh *github) GetPullRequestRequestedReviewer(prNumber string) (string, error) { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber) + + var requestedReviewers struct { + Users []struct { + Login string `json:"login"` + } `json:"users"` + } + + _, err := utils.RequestCall(url, "GET", gh.token, &requestedReviewers, nil) + if err != nil { + return "", err + } + + if requestedReviewers.Users == nil || len(requestedReviewers.Users) == 0 { + return "", nil + } + + return requestedReviewers.Users[0].Login, nil +} + +func (gh *github) GetPullRequestPreviousAssignedReviewers(prNumber string) ([]string, error) { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/reviews", prNumber) + + var reviews []struct { + User struct { + Login string `json:"login"` + } `json:"user"` + } + + _, err := utils.RequestCall(url, "GET", gh.token, &reviews, nil) + if err != nil { + return nil, err + } + + previousAssignedReviewers := map[string]struct{}{} + for _, review := range reviews { + previousAssignedReviewers[review.User.Login] = struct{}{} + } + + result := []string{} + for key, _ := range previousAssignedReviewers { + result = append(result, key) + } + + return result, nil +} diff --git a/.ci/magician/github/init.go b/.ci/magician/github/init.go new file mode 100644 index 000000000000..66847f0fc628 --- /dev/null +++ b/.ci/magician/github/init.go @@ -0,0 +1,33 @@ +package github + +import ( + "fmt" + "os" +) + +// GithubService represents the service for GitHub interactions. +type github struct { + token string +} + +type GithubService interface { + GetPullRequestAuthor(prNumber string) (string, error) + GetPullRequestRequestedReviewer(prNumber string) (string, error) + GetPullRequestPreviousAssignedReviewers(prNumber string) ([]string, error) + GetUserType(user string) UserType + PostBuildStatus(prNumber, title, state, target_url, commitSha string) error + PostComment(prNumber, comment string) error + RequestPullRequestReviewer(prNumber, assignee string) error + AddLabel(prNumber, label string) error + RemoveLabel(prNumber, label string) error +} + +func NewGithubService() GithubService { + GITHUB_TOKEN, ok := os.LookupEnv("GITHUB_TOKEN") + if !ok { + fmt.Println("Did not provide GITHUB_TOKEN environment variable") + os.Exit(1) + } + + return &github{token: GITHUB_TOKEN} +} diff --git a/.ci/magician/github/membership.go b/.ci/magician/github/membership.go new file mode 100644 index 000000000000..6ed6a6da7395 --- /dev/null +++ b/.ci/magician/github/membership.go @@ -0,0 +1,98 @@ +package github + +import ( + "fmt" + utils "magician/utility" + "math/rand" + "time" + + "golang.org/x/exp/slices" +) + +var ( + // This is for the random-assignee rotation. + reviewerRotation = []string{ + "slevenick", + "c2thorn", + "rileykarson", + "melinath", + "ScottSuarez", + "shuyama1", + "SarahFrench", + "roaks3", + "zli82016", + "trodge", + "hao-nan-li", + "NickElliot", + } + + // This is for new team members who are onboarding + trustedContributors = []string{} + + // This is for reviewers who are "on vacation": will not receive new review assignments but will still receive re-requests for assigned PRs. + onVacationReviewers = []string{ + "slevenick", + "roaks3", + } +) + +type UserType int64 + +const ( + CommunityUserType UserType = iota + GooglerUserType + CoreContributorUserType +) + +func (ut UserType) String() string { + switch ut { + case GooglerUserType: + return "Googler" + case CoreContributorUserType: + return "Core Contributor" + default: + return "Community Contributor" + } +} + +func (gh *github) GetUserType(user string) UserType { + if isTeamMember(user, gh.token) { + fmt.Println("User is a team member") + return CoreContributorUserType + } + + if isOrgMember(user, "GoogleCloudPlatform", gh.token) { + fmt.Println("User is a GCP org member") + return GooglerUserType + } + + if isOrgMember(user, "googlers", gh.token) { + fmt.Println("User is a googlers org member") + return GooglerUserType + } + + return CommunityUserType +} + +// Check if a user is team member to not request a random reviewer +func isTeamMember(author, githubToken string) bool { + return slices.Contains(reviewerRotation, author) || slices.Contains(trustedContributors, author) +} + +func isTeamReviewer(reviewer string) bool { + return slices.Contains(reviewerRotation, reviewer) +} + +func isOrgMember(author, org, githubToken string) bool { + url := fmt.Sprintf("https://api.github.com/orgs/%s/members/%s", org, author) + res, _ := utils.RequestCall(url, "GET", githubToken, nil, nil) + + return res != 404 +} + +func GetRandomReviewer() string { + availableReviewers := utils.Removes(reviewerRotation, onVacationReviewers) + rand.Seed(time.Now().UnixNano()) + reviewer := availableReviewers[rand.Intn(len(availableReviewers))] + return reviewer +} diff --git a/.ci/magician/github/membership_test.go b/.ci/magician/github/membership_test.go new file mode 100644 index 000000000000..1f2264bdf3c2 --- /dev/null +++ b/.ci/magician/github/membership_test.go @@ -0,0 +1,23 @@ +package github + +import ( + "testing" + + "golang.org/x/exp/slices" +) + +func TestTrustedContributors(t *testing.T) { + for _, member := range trustedContributors { + if slices.Contains(reviewerRotation, member) { + t.Fatalf(`%v should not be on reviewerRotation list`, member) + } + } +} + +func TestOnVacationReviewers(t *testing.T) { + for _, member := range onVacationReviewers { + if !slices.Contains(reviewerRotation, member) { + t.Fatalf(`%v is not on reviewerRotation list`, member) + } + } +} diff --git a/.ci/magician/github/reviewer_assignment.go b/.ci/magician/github/reviewer_assignment.go new file mode 100644 index 000000000000..912de41dfa5d --- /dev/null +++ b/.ci/magician/github/reviewer_assignment.go @@ -0,0 +1,52 @@ +package github + +import ( + "fmt" + "strings" + "text/template" + + _ "embed" +) + +var ( + //go:embed REVIEWER_ASSIGNMENT_COMMENT.md + reviewerAssignmentComment string +) + +// Returns a list of users to request review from, as well as a new primary reviewer if this is the first run. +func ChooseReviewers(firstRequestedReviewer string, previouslyInvolvedReviewers []string) (reviewersToRequest []string, newPrimaryReviewer string) { + hasPrimaryReviewer := false + newPrimaryReviewer = "" + + if firstRequestedReviewer != "" { + hasPrimaryReviewer = true + } + + for _, reviewer := range previouslyInvolvedReviewers { + if isTeamReviewer(reviewer) { + hasPrimaryReviewer = true + reviewersToRequest = append(reviewersToRequest, reviewer) + } + } + + if !hasPrimaryReviewer { + newPrimaryReviewer = GetRandomReviewer() + reviewersToRequest = append(reviewersToRequest, newPrimaryReviewer) + } + + return reviewersToRequest, newPrimaryReviewer +} + +func FormatReviewerComment(newPrimaryReviewer string, authorUserType UserType, trusted bool) string { + tmpl, err := template.New("REVIEWER_ASSIGNMENT_COMMENT.md").Parse(reviewerAssignmentComment) + if err != nil { + panic(fmt.Sprintf("Unable to parse REVIEWER_ASSIGNMENT_COMMENT.md: %s", err)) + } + sb := new(strings.Builder) + tmpl.Execute(sb, map[string]interface{}{ + "reviewer": newPrimaryReviewer, + "authorUserType": authorUserType.String(), + "trusted": trusted, + }) + return sb.String() +} diff --git a/.ci/magician/github/reviewer_assignment_test.go b/.ci/magician/github/reviewer_assignment_test.go new file mode 100644 index 000000000000..b96ac59a7389 --- /dev/null +++ b/.ci/magician/github/reviewer_assignment_test.go @@ -0,0 +1,136 @@ +package github + +import ( + "fmt" + utils "magician/utility" + "strings" + "testing" + + "golang.org/x/exp/slices" +) + +func TestChooseReviewers(t *testing.T) { + cases := map[string]struct { + FirstRequestedReviewer string + PreviouslyInvolvedReviewers []string + ExpectReviewersFromList, ExpectSpecificReviewers []string + ExpectPrimaryReviewer bool + }{ + "no previous review requests assigns new reviewer from team": { + FirstRequestedReviewer: "", + PreviouslyInvolvedReviewers: []string{}, + ExpectReviewersFromList: utils.Removes(reviewerRotation, onVacationReviewers), + ExpectPrimaryReviewer: true, + }, + "first requested reviewer means that primary reviewer was already selected": { + FirstRequestedReviewer: "foobar", + PreviouslyInvolvedReviewers: []string{}, + ExpectPrimaryReviewer: false, + }, + "previously involved team member reviewers should have review requested and mean that primary reviewer was already selected": { + FirstRequestedReviewer: "", + PreviouslyInvolvedReviewers: []string{reviewerRotation[0]}, + ExpectSpecificReviewers: []string{reviewerRotation[0]}, + ExpectPrimaryReviewer: false, + }, + "previously involved reviewers that are not team members are ignored": { + FirstRequestedReviewer: "", + PreviouslyInvolvedReviewers: []string{"foobar"}, + ExpectReviewersFromList: utils.Removes(reviewerRotation, onVacationReviewers), + ExpectPrimaryReviewer: true, + }, + "only previously involved team member reviewers will have review requested": { + FirstRequestedReviewer: "", + PreviouslyInvolvedReviewers: []string{reviewerRotation[0], "foobar", reviewerRotation[1]}, + ExpectSpecificReviewers: []string{reviewerRotation[0], reviewerRotation[1]}, + ExpectPrimaryReviewer: false, + }, + "primary reviewer will not have review requested even if other team members previously reviewed": { + FirstRequestedReviewer: reviewerRotation[1], + PreviouslyInvolvedReviewers: []string{reviewerRotation[0]}, + ExpectSpecificReviewers: []string{reviewerRotation[0]}, + ExpectPrimaryReviewer: false, + }, + } + + for tn, tc := range cases { + tc := tc + t.Run(tn, func(t *testing.T) { + t.Parallel() + reviewers, primaryReviewer := ChooseReviewers(tc.FirstRequestedReviewer, tc.PreviouslyInvolvedReviewers) + if tc.ExpectPrimaryReviewer && primaryReviewer == "" { + t.Error("wanted primary reviewer to be returned; got none") + } + if !tc.ExpectPrimaryReviewer && primaryReviewer != "" { + t.Errorf("wanted no primary reviewer; got %s", primaryReviewer) + } + if len(tc.ExpectReviewersFromList) > 0 { + for _, reviewer := range reviewers { + if !slices.Contains(tc.ExpectReviewersFromList, reviewer) { + t.Errorf("wanted reviewer %s to be in list %v but they were not", reviewer, tc.ExpectReviewersFromList) + } + } + } + if len(tc.ExpectSpecificReviewers) > 0 { + if !slices.Equal(reviewers, tc.ExpectSpecificReviewers) { + t.Errorf("wanted reviewers to be %v; instead got %v", tc.ExpectSpecificReviewers, reviewers) + } + } + }) + } +} + +func TestFormatReviewerComment(t *testing.T) { + cases := map[string]struct { + Reviewer string + AuthorUserType UserType + Trusted bool + }{ + "community contributor": { + Reviewer: "foobar", + AuthorUserType: CommunityUserType, + Trusted: false, + }, + "googler": { + Reviewer: "foobar", + AuthorUserType: GooglerUserType, + Trusted: true, + }, + "core contributor": { + Reviewer: "foobar", + AuthorUserType: CoreContributorUserType, + Trusted: true, + }, + } + + for tn, tc := range cases { + tc := tc + t.Run(tn, func(t *testing.T) { + t.Parallel() + comment := FormatReviewerComment(tc.Reviewer, tc.AuthorUserType, tc.Trusted) + t.Log(comment) + if !strings.Contains(comment, fmt.Sprintf("@%s", tc.Reviewer)) { + t.Errorf("wanted comment to contain @%s; does not.", tc.Reviewer) + } + if !strings.Contains(comment, tc.AuthorUserType.String()) { + t.Errorf("wanted comment to contain user type (%s); does not.", tc.AuthorUserType.String()) + } + if strings.Contains(comment, fmt.Sprintf("~%s~", tc.AuthorUserType.String())) { + t.Errorf("wanted user type (%s) in comment to not be crossed out, but it is", tc.AuthorUserType.String()) + } + for _, ut := range []UserType{CommunityUserType, GooglerUserType, CoreContributorUserType} { + if ut != tc.AuthorUserType && !strings.Contains(comment, fmt.Sprintf("~%s~", ut.String())) { + t.Errorf("wanted other user type (%s) in comment to be crossed out, but it is not", ut) + } + } + + if tc.Trusted && !strings.Contains(comment, "Tests will run automatically") { + t.Errorf("wanted comment to say tests will run automatically; does not") + } + if !tc.Trusted && !strings.Contains(comment, "Tests will require approval") { + t.Errorf("wanted comment to say tests will require approval; does not") + } + }) + + } +} diff --git a/.ci/magician/github/set.go b/.ci/magician/github/set.go new file mode 100644 index 000000000000..a7893b3cf83b --- /dev/null +++ b/.ci/magician/github/set.go @@ -0,0 +1,96 @@ +package github + +import ( + "fmt" + utils "magician/utility" + "net/http" +) + +func (gh *github) PostBuildStatus(prNumber, title, state, target_url, commitSha string) error { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/statuses/%s", commitSha) + + postBody := map[string]string{ + "context": title, + "state": state, + "target_url": target_url, + } + + _, err := utils.RequestCall(url, "POST", gh.token, nil, postBody) + if err != nil { + return err + } + + fmt.Printf("Successfully posted build status to pull request %s\n", prNumber) + + return nil +} + +func (gh *github) PostComment(prNumber, comment string) error { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/%s/comments", prNumber) + + body := map[string]string{ + "body": comment, + } + + reqStatusCode, err := utils.RequestCall(url, "POST", gh.token, nil, body) + if err != nil { + return err + } + + if reqStatusCode != http.StatusCreated { + return fmt.Errorf("error posting comment for PR %s", prNumber) + } + + fmt.Printf("Successfully posted comment to pull request %s\n", prNumber) + + return nil +} + +func (gh *github) RequestPullRequestReviewer(prNumber, assignee string) error { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber) + + body := map[string][]string{ + "reviewers": {assignee}, + "team_reviewers": {}, + } + + reqStatusCode, err := utils.RequestCall(url, "POST", gh.token, nil, body) + if err != nil { + return err + } + + if reqStatusCode != http.StatusCreated { + return fmt.Errorf("error adding reviewer for PR %s", prNumber) + } + + fmt.Printf("Successfully added reviewer %s to pull request %s\n", assignee, prNumber) + + return nil +} + +func (gh *github) AddLabel(prNumber, label string) error { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/%s/labels", prNumber) + + body := map[string][]string{ + "labels": {label}, + } + _, err := utils.RequestCall(url, "POST", gh.token, nil, body) + + if err != nil { + return fmt.Errorf("failed to add %s label: %s", label, err) + } + + return nil + +} + +func (gh *github) RemoveLabel(prNumber, label string) error { + url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/%s/labels/%s", prNumber, label) + _, err := utils.RequestCall(url, "DELETE", gh.token, nil, nil) + + if err != nil { + return fmt.Errorf("failed to remove %s label: %s", label, err) + } + + return nil +} diff --git a/.ci/magician/go.mod b/.ci/magician/go.mod new file mode 100644 index 000000000000..864ebd1e2c08 --- /dev/null +++ b/.ci/magician/go.mod @@ -0,0 +1,30 @@ +module magician + +go 1.19 + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/exp v0.0.0-20230314191032-db074128a8ec + google.golang.org/api v0.112.0 +) + +require ( + cloud.google.com/go/compute v1.18.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488 // indirect + google.golang.org/grpc v1.53.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect +) diff --git a/.ci/magician/go.sum b/.ci/magician/go.sum new file mode 100644 index 000000000000..1fa5659b8306 --- /dev/null +++ b/.ci/magician/go.sum @@ -0,0 +1,143 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230314191032-db074128a8ec h1:pAv+d8BM2JNnNctsLJ6nnZ6NqXT8N4+eauvZSb3P0I0= +golang.org/x/exp v0.0.0-20230314191032-db074128a8ec/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.112.0 h1:iDmzvZ4C086R3+en4nSyIf07HlQKMOX1Xx2dmia/+KQ= +google.golang.org/api v0.112.0/go.mod h1:737UfWHNsOq4F3REUTmb+GN9pugkgNLCayLTfoIKpPc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488 h1:QQF+HdiI4iocoxUjjpLgvTYDHKm99C/VtTBFnfiCJos= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/.ci/magician/main.go b/.ci/magician/main.go new file mode 100644 index 000000000000..7cf107ae4fbc --- /dev/null +++ b/.ci/magician/main.go @@ -0,0 +1,11 @@ +/* +Copyright © 2023 NAME HERE + +*/ +package main + +import "magician/cmd" + +func main() { + cmd.Execute() +} diff --git a/.ci/magician/utility/utils.go b/.ci/magician/utility/utils.go new file mode 100644 index 000000000000..2f7b66df0d43 --- /dev/null +++ b/.ci/magician/utility/utils.go @@ -0,0 +1,48 @@ +package utility + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + "golang.org/x/exp/slices" +) + +func RequestCall(url, method, credentials string, result interface{}, body interface{}) (int, error) { + client := &http.Client{} + jsonBody, err := json.Marshal(body) + if err != nil { + return 1, fmt.Errorf("error marshaling JSON: %s", err) + } + req, err := http.NewRequest(method, url, bytes.NewBuffer(jsonBody)) + if err != nil { + return 2, fmt.Errorf("error creating request: %s", err) + } + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", credentials)) + req.Header.Set("Content-Type", "application/json") + resp, err := client.Do(req) + if err != nil { + return 3, err + } + defer resp.Body.Close() + + if result != nil { + if err = json.NewDecoder(resp.Body).Decode(&result); err != nil { + return 4, err + } + } + + return resp.StatusCode, nil +} + +func Removes(s1 []string, s2 []string) []string { + result := make([]string, 0, len(s1)) + + for _, v := range s1 { + if !slices.Contains(s2, v) { + result = append(result, v) + } + } + return result +} diff --git a/.ci/magician/utility/utils_test.go b/.ci/magician/utility/utils_test.go new file mode 100644 index 000000000000..2f82538ab7c1 --- /dev/null +++ b/.ci/magician/utility/utils_test.go @@ -0,0 +1,49 @@ +package utility + +import ( + "reflect" + "testing" +) + +func TestRemovesList(t *testing.T) { + cases := map[string]struct { + Original, Removal, Expected []string + }{ + "Remove list": { + Original: []string{"a", "b", "c"}, + Removal: []string{"b"}, + Expected: []string{"a", "c"}, + }, + "Remove case sensitive elements": { + Original: []string{"a", "b", "c", "A", "B"}, + Removal: []string{"b", "c", "A"}, + Expected: []string{"a", "B"}, + }, + "Remove nonexistent elements": { + Original: []string{"a", "b", "c", "A", "B"}, + Removal: []string{"a", "A", "d"}, + Expected: []string{"b", "c", "B"}, + }, + "Remove none": { + Original: []string{"a", "b", "c", "A", "B"}, + Removal: []string{}, + Expected: []string{"a", "b", "c", "A", "B"}, + }, + "Remove all": { + Original: []string{"a", "b", "c", "A", "B"}, + Removal: []string{"a", "b", "c", "A", "B"}, + Expected: []string{}, + }, + "Remove all and extra nonexistent elements": { + Original: []string{"a", "b", "c", "A", "B"}, + Removal: []string{"a", "b", "c", "A", "B", "D"}, + Expected: []string{}, + }, + } + for tn, tc := range cases { + result := Removes(tc.Original, tc.Removal) + if !reflect.DeepEqual(result, tc.Expected) { + t.Errorf("bad: %s, '%s' removes '%s' expect result: %s, but got: %s", tn, tc.Original, tc.Removal, tc.Expected, result) + } + } +} diff --git a/.ci/scripts/go-plus/magician/exec.sh b/.ci/scripts/go-plus/magician/exec.sh new file mode 100755 index 000000000000..32abb017defa --- /dev/null +++ b/.ci/scripts/go-plus/magician/exec.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Check if there's at least one argument +if [ "$#" -eq 0 ]; then + echo "No arguments provided" + exit 1 +fi + +# Get the directory of the current script +DIR="$(dirname $(realpath $0))" + +# Construct the path to the Go program +GO_PROGRAM="$DIR/../../../magician/" + +pushd $GO_PROGRAM + +# Pass all arguments to the child command +go run . "$@" diff --git a/.github/workflows/membership-checker.yml b/.github/workflows/membership-checker.yml index a0c9b392599a..fbc1d10bba62 100644 --- a/.github/workflows/membership-checker.yml +++ b/.github/workflows/membership-checker.yml @@ -5,7 +5,7 @@ permissions: read-all on: pull_request: paths: - - '.ci/containers/membership-checker/**' + - '.ci/magician/**' jobs: build-and-unit-tests: @@ -18,5 +18,5 @@ jobs: go-version: '^1.19.1' - name: Run membership checker unit tests run: | - cd .ci/containers/membership-checker - go test -v + cd .ci/magician + go test ./... -v From 1c54afeaa1c00851d351ef3dd0c27bf8d77eb0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=BC=E4=BA=9A?= <4006891+ch3ck@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:17:17 -0700 Subject: [PATCH 053/476] feat: add env block to cloud workstations resource. (#8911) --- mmv1/products/workstations/Workstation.yaml | 4 ++++ .../templates/terraform/examples/workstation_basic.tf.erb | 4 ++++ .../resource_workstations_workstation_test.go.erb | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/mmv1/products/workstations/Workstation.yaml b/mmv1/products/workstations/Workstation.yaml index fca8d282c316..39608a4ba043 100644 --- a/mmv1/products/workstations/Workstation.yaml +++ b/mmv1/products/workstations/Workstation.yaml @@ -125,6 +125,10 @@ properties: - !ruby/object:Api::Type::KeyValuePairs name: 'annotations' description: 'Client-specified annotations. This is distinct from labels.' + - !ruby/object:Api::Type::KeyValuePairs + name: 'env' + description: | + 'Client-specified environment variables passed to the workstation container's entrypoint.' - !ruby/object:Api::Type::Time name: 'createTime' description: | diff --git a/mmv1/templates/terraform/examples/workstation_basic.tf.erb b/mmv1/templates/terraform/examples/workstation_basic.tf.erb index 2cfb2b733912..b5432bd1c060 100644 --- a/mmv1/templates/terraform/examples/workstation_basic.tf.erb +++ b/mmv1/templates/terraform/examples/workstation_basic.tf.erb @@ -54,6 +54,10 @@ resource "google_workstations_workstation" "<%= ctx[:primary_resource_id] %>" { "label" = "key" } + env = { + name = "foo" + } + annotations = { label-one = "value-one" } diff --git a/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_test.go.erb b/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_test.go.erb index 1c0bc6af56dd..9e06368ceb1a 100644 --- a/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_test.go.erb +++ b/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_test.go.erb @@ -88,6 +88,10 @@ resource "google_workstations_workstation" "default" { labels = { foo = "bar" } + + env = { + name = "bar" + } } `, context) } @@ -137,6 +141,10 @@ resource "google_workstations_workstation" "default" { labels = { foo = "bar" } + + env = { + name = "test" + } } `, context) } From acdfd68bf7acb86ab7df0107631c073a62ec67f3 Mon Sep 17 00:00:00 2001 From: Scott Suarez Date: Tue, 12 Sep 2023 15:36:42 -0700 Subject: [PATCH 054/476] Make `location` required on `google_cloudfunctions2_function` (#8928) --- mmv1/products/cloudfunctions2/Function.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/mmv1/products/cloudfunctions2/Function.yaml b/mmv1/products/cloudfunctions2/Function.yaml index 69d5e04907b7..a8ca2d64185a 100644 --- a/mmv1/products/cloudfunctions2/Function.yaml +++ b/mmv1/products/cloudfunctions2/Function.yaml @@ -251,6 +251,7 @@ parameters: - !ruby/object:Api::Type::String name: 'location' immutable: true + required: true url_param_only: true description: The location of this cloud function. properties: From ccc68deb0101b0c658991ee2dea984ae1f116e5c Mon Sep 17 00:00:00 2001 From: Scott Suarez Date: Tue, 12 Sep 2023 15:37:00 -0700 Subject: [PATCH 055/476] Transitioned `volumes.cloud_sql_instance.instances` to SET from array (#8929) --- mmv1/products/cloudrunv2/Service.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index db919ee81e51..337e63381f52 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -690,6 +690,7 @@ properties: description: |- The Cloud SQL instance connection names, as can be found in https://console.cloud.google.com/sql/instances. Visit https://cloud.google.com/sql/docs/mysql/connect-run for more information on how to connect Cloud SQL and Cloud Run. Format: {project}:{location}:{instance} item_type: Api::Type::String + is_set: true - !ruby/object:Api::Type::NestedObject name: 'emptyDir' description: |- From 86b9c51de3e97f852b6b0b721582a155196f1b28 Mon Sep 17 00:00:00 2001 From: Ethan Truong Date: Wed, 13 Sep 2023 11:41:32 -0400 Subject: [PATCH 056/476] Fix issue #12883 (#8738) * Fix issue #12883 Make one CloudResourceManager call per monitored_project terraform resource rather than per (monitored_project * "sibling" projects) * Add comment * Correct build errors * Fix build errors * Add debug logs * Fix printf * Fix match between TF resource and API response * Fix from non-matching to matching condition * Correct documentation * Correct documentation * Fix go build issues * Convert projectNumber to string * Use correct string conversion * Move comment * Add debug logs to monitored project encoder * correct delete_url --- .../products/monitoring/MonitoredProject.yaml | 5 +-- .../monitoring_monitored_project.go.erb | 44 +++++++++++++------ .../monitoring_monitored_project.go.erb | 4 ++ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/mmv1/products/monitoring/MonitoredProject.yaml b/mmv1/products/monitoring/MonitoredProject.yaml index bc06bfa0b8cc..135065548d06 100644 --- a/mmv1/products/monitoring/MonitoredProject.yaml +++ b/mmv1/products/monitoring/MonitoredProject.yaml @@ -15,7 +15,7 @@ name: MonitoredProject base_url: v1/locations/global/metricsScopes create_url: v1/locations/global/metricsScopes/{{metrics_scope}}/projects -delete_url: v1/locations/global/metricsScopes/{{metrics_scope}}/projects/{{name}} +delete_url: v1/{{name}} self_link: v1/locations/global/metricsScopes/{{metrics_scope}} id_format: locations/global/metricsScopes/{{metrics_scope}}/projects/{{name}} schema_version: 1 @@ -24,9 +24,6 @@ references: !ruby/object:Api::Resource::ReferenceLinks guides: 'Official Documentation': 'https://cloud.google.com/monitoring/settings/manage-api' api: 'https://cloud.google.com/monitoring/api/ref_v3/rest/v1/locations.global.metricsScopes.projects' -nested_query: !ruby/object:Api::Resource::NestedQuery - keys: - - monitoredProjects description: "A [project being monitored](https://cloud.google.com/monitoring/settings/multiple-projects#create-multi) by a Metrics Scope." immutable: true error_retry_predicates: ['transport_tpg.IsMonitoringPermissionError'] diff --git a/mmv1/templates/terraform/decoders/monitoring_monitored_project.go.erb b/mmv1/templates/terraform/decoders/monitoring_monitored_project.go.erb index c9bd178663b8..68afb6097983 100644 --- a/mmv1/templates/terraform/decoders/monitoring_monitored_project.go.erb +++ b/mmv1/templates/terraform/decoders/monitoring_monitored_project.go.erb @@ -12,23 +12,39 @@ # See the License for the specific language governing permissions and # limitations under the License. -%> +// terraform resource config config := meta.(*transport_tpg.Config) -expectedName, _ := expandNestedMonitoringMonitoredProjectName(d.Get("name"), d, config) -expectedFlattenedName := flattenNestedMonitoringMonitoredProjectName(expectedName, d, config) -_, isNumErr := tpgresource.StringToFixed64(expectedFlattenedName.(string)) -expectProjectNumber := isNumErr == nil +// The API returns all monitored projects +monitoredProjects, _ := res["monitoredProjects"].([]interface{}) -name := res["name"].(string) -name = tpgresource.GetResourceNameFromSelfLink(name) +// Convert configured terraform monitored_project resource name to a ProjectNumber +expectedProject, configProjectErr := config.NewResourceManagerClient(config.UserAgent).Projects.Get(d.Get("name").(string)).Do() +if configProjectErr != nil { + return nil, configProjectErr +} +expectedProjectNumber := strconv.FormatInt(expectedProject.ProjectNumber, 10) + +log.Printf("[DEBUG] Scanning for ProjectNumber: %s.", expectedProjectNumber) + +// Iterate through the list of monitoredProjects to make sure one matches the configured monitored_project +for _, monitoredProjectRaw := range monitoredProjects { + if monitoredProjectRaw == nil { + continue + } + monitoredProject := monitoredProjectRaw.(map[string]interface{}) + + // MonitoredProject names have the format locations/global/metricsScopes/[metricScopeProjectNumber]/projects/[projectNumber] + monitoredProjectName := monitoredProject["name"] -if expectProjectNumber { - res["name"] = name -} else if name != "" { - project, err := config.NewResourceManagerClient(config.UserAgent).Projects.Get(name).Do() - if err != nil { - return nil, err + // `res` contains the MonitoredProjects of the relevant metrics scope + log.Printf("[DEBUG] Matching ProjectNumbers: %s to %s.", expectedProjectNumber, monitoredProjectName) + if strings.HasSuffix(monitoredProjectName.(string), fmt.Sprintf("/%s", expectedProjectNumber)) { + // Match found - set response object name to match + res["name"] = monitoredProjectName + log.Printf("[DEBUG] Matched ProjectNumbers: %s and %s.", expectedProjectNumber, monitoredProjectName) + return res, nil } - res["name"] = project.ProjectId } -return res, nil +log.Printf("[DEBUG] MonitoringMonitoredProject couldn't be matched.") +return nil, nil diff --git a/mmv1/templates/terraform/encoders/monitoring_monitored_project.go.erb b/mmv1/templates/terraform/encoders/monitoring_monitored_project.go.erb index 94012980b429..1dc444ecb132 100644 --- a/mmv1/templates/terraform/encoders/monitoring_monitored_project.go.erb +++ b/mmv1/templates/terraform/encoders/monitoring_monitored_project.go.erb @@ -13,10 +13,14 @@ # limitations under the License. -%> name := d.Get("name").(string) +log.Printf("[DEBUG] Encoded monitored project name: %s", name) name = tpgresource.GetResourceNameFromSelfLink(name) +log.Printf("[DEBUG] Encoded monitored project resource name: %s", name) d.Set("name", name) metricsScope := d.Get("metrics_scope").(string) +log.Printf("[DEBUG] Encoded monitored project metricsScope: %s", metricsScope) metricsScope = tpgresource.GetResourceNameFromSelfLink(metricsScope) +log.Printf("[DEBUG] Encoded monitored project metricsScope resource name: %s", metricsScope) d.Set("metrics_scope", metricsScope) obj["name"] = fmt.Sprintf("locations/global/metricsScopes/%s/projects/%s", metricsScope, name) return obj, nil From dee0a2a621ac58ae5fa06a0d443f4dd206c251fb Mon Sep 17 00:00:00 2001 From: pokutuna Date: Thu, 14 Sep 2023 02:16:23 +0900 Subject: [PATCH 057/476] Fix broken link in docs (#8940) --- docs/content/contribute/create-pr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/contribute/create-pr.md b/docs/content/contribute/create-pr.md index 1711e8207206..e068093e985e 100644 --- a/docs/content/contribute/create-pr.md +++ b/docs/content/contribute/create-pr.md @@ -24,7 +24,7 @@ weight: 10 **TIP:** Speeding up review: 1. Resolve failed [status checks](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks) quickly - Ask your reviewer for help if you get stuck. -1. [Self-review your PR]({{< ref "/contribute/review-pr" >}}") or ask someone you know to review +1. [Self-review your PR]({{< ref "/contribute/review-pr" >}}) or ask someone you know to review {{< /hint >}} From 75dcc62694b06c8a8de1b4bb90da88a97c4fb082 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Wed, 13 Sep 2023 11:44:35 -0700 Subject: [PATCH 058/476] Support provider default labels for DCL resources (#8893) --- .../resource_clouddeploy_target_test.go | 278 ++++++++++++++++++ ...rce_dataproc_workflow_template_test.go.erb | 4 +- tpgtools/property.go | 37 ++- tpgtools/resource.go | 14 +- tpgtools/templates/resource.go.tmpl | 19 +- tpgtools/templates/serialization.go.tmpl | 2 +- 6 files changed, 345 insertions(+), 9 deletions(-) create mode 100644 mmv1/third_party/terraform/services/clouddeploy/resource_clouddeploy_target_test.go diff --git a/mmv1/third_party/terraform/services/clouddeploy/resource_clouddeploy_target_test.go b/mmv1/third_party/terraform/services/clouddeploy/resource_clouddeploy_target_test.go new file mode 100644 index 000000000000..e8393b2a09ba --- /dev/null +++ b/mmv1/third_party/terraform/services/clouddeploy/resource_clouddeploy_target_test.go @@ -0,0 +1,278 @@ +package clouddeploy_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 TestAccClouddeployTarget_withProviderDefaultLabels(t *testing.T) { + // The test failed if VCR testing is enabled, because the cached provider config is used. + // Any changes in the provider default labels will not be applied. + acctest.SkipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "project_name": envvar.GetTestProjectFromEnv(), + "region": envvar.GetTestRegionFromEnv(), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckClouddeployTargetDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccClouddeployTarget_withProviderDefaultLabels(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.%", "2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_second_label", "example-label-2"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_second_label", "example-label-2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.default_key1", "default_value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_clouddeploy_target.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels", "annotations"}, + }, + { + Config: testAccClouddeployTarget_resourceLabelsOverridesProviderDefaultLabels(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.%", "3"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_second_label", "example-label-2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_second_label", "example-label-2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_clouddeploy_target.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels", "annotations"}, + }, + { + Config: testAccClouddeployTarget_moveResourceLabelToProviderDefaultLabels(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.%", "2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_second_label", "example-label-2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_clouddeploy_target.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels", "annotations"}, + }, + { + Config: testAccClouddeployTarget_resourceLabelsOverridesProviderDefaultLabels(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.%", "3"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.my_second_label", "example-label-2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.%", "3"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_first_label", "example-label-1"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.my_second_label", "example-label-2"), + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "terraform_labels.default_key1", "value1"), + + resource.TestCheckResourceAttr("google_clouddeploy_target.primary", "effective_labels.%", "3"), + ), + }, + { + ResourceName: "google_clouddeploy_target.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels", "annotations"}, + }, + { + Config: testAccClouddeployTarget_withoutLabels(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckNoResourceAttr("google_clouddeploy_target.primary", "labels.%"), + resource.TestCheckNoResourceAttr("google_clouddeploy_target.primary", "terraform_labels.%"), + resource.TestCheckNoResourceAttr("google_clouddeploy_target.primary", "effective_labels.%"), + ), + }, + { + ResourceName: "google_clouddeploy_target.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels", "annotations"}, + }, + }, + }) +} + +func testAccClouddeployTarget_withProviderDefaultLabels(context map[string]interface{}) string { + return acctest.Nprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + } +} + +resource "google_clouddeploy_target" "primary" { + location = "%{region}" + name = "tf-test-target%{random_suffix}" + + deploy_parameters = { + deployParameterKey = "deployParameterValue" + } + + description = "basic description" + + gke { + cluster = "projects/%{project_name}/locations/%{region}/clusters/example-cluster-name" + } + + project = "%{project_name}" + require_approval = false + + annotations = { + my_first_annotation = "example-annotation-1" + + my_second_annotation = "example-annotation-2" + } + + labels = { + my_first_label = "example-label-1" + my_second_label = "example-label-2" + } +} +`, context) +} + +func testAccClouddeployTarget_resourceLabelsOverridesProviderDefaultLabels(context map[string]interface{}) string { + return acctest.Nprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + } +} + +resource "google_clouddeploy_target" "primary" { + location = "%{region}" + name = "tf-test-target%{random_suffix}" + + deploy_parameters = { + deployParameterKey = "deployParameterValue" + } + + description = "basic description" + + gke { + cluster = "projects/%{project_name}/locations/%{region}/clusters/example-cluster-name" + } + + project = "%{project_name}" + require_approval = false + + annotations = { + my_first_annotation = "example-annotation-1" + + my_second_annotation = "example-annotation-2" + } + + labels = { + my_first_label = "example-label-1" + my_second_label = "example-label-2" + default_key1 = "value1" + } +} +`, context) +} + +func testAccClouddeployTarget_moveResourceLabelToProviderDefaultLabels(context map[string]interface{}) string { + return acctest.Nprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + my_second_label = "example-label-2" + } +} + +resource "google_clouddeploy_target" "primary" { + location = "%{region}" + name = "tf-test-target%{random_suffix}" + + deploy_parameters = { + deployParameterKey = "deployParameterValue" + } + + description = "basic description" + + gke { + cluster = "projects/%{project_name}/locations/%{region}/clusters/example-cluster-name" + } + + project = "%{project_name}" + require_approval = false + + annotations = { + my_first_annotation = "example-annotation-1" + + my_second_annotation = "example-annotation-2" + } + + labels = { + my_first_label = "example-label-1" + default_key1 = "value1" + } +} +`, context) +} + +func testAccClouddeployTarget_withoutLabels(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_clouddeploy_target" "primary" { + location = "%{region}" + name = "tf-test-target%{random_suffix}" + + deploy_parameters = { + deployParameterKey = "deployParameterValue" + } + + description = "basic description" + + gke { + cluster = "projects/%{project_name}/locations/%{region}/clusters/example-cluster-name" + } + + project = "%{project_name}" + require_approval = false + + annotations = { + my_first_annotation = "example-annotation-1" + + my_second_annotation = "example-annotation-2" + } +} +`, context) +} diff --git a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_workflow_template_test.go.erb b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_workflow_template_test.go.erb index aa3dc64a6223..21988d0cb673 100644 --- a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_workflow_template_test.go.erb +++ b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_workflow_template_test.go.erb @@ -38,9 +38,9 @@ func TestAccDataprocWorkflowTemplate_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, // The "labels" field in the state are decided by the configuration. - // During importing, as the configuration is unavailableafter, the "labels" field in the state will be empty. + // During importing, as the configuration is unavailable, the "labels" field in the state will be empty. // So add the "labels" to the ImportStateVerifyIgnore list. - ImportStateVerifyIgnore: []string{"labels"}, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, ResourceName: "google_dataproc_workflow_template.template", }, }, diff --git a/tpgtools/property.go b/tpgtools/property.go index 0292c3124857..f95c8ddbb089 100644 --- a/tpgtools/property.go +++ b/tpgtools/property.go @@ -452,6 +452,10 @@ func (p Property) IsResourceAnnotations() bool { return p.Name() == "annotations" && p.parent == nil } +func (p Property) ShouldShowUpInSamples() bool { + return (p.Settable && p.Name() != "effective_labels" && p.Name() != "effective_annotations") || p.IsResourceLabels() || p.IsResourceAnnotations() +} + // collapsedProperties returns the input list of properties with nested objects collapsed if needed. func collapsedProperties(props []Property) (collapsed []Property) { for _, v := range props { @@ -897,7 +901,14 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher note := "**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." p.Description = fmt.Sprintf("%s\n\n%s", p.Description, note) + p.Settable = false + p.StateGetter = nil + props = append(props, build_effective_labels_field(p, resource, parent)) + + if p.IsResourceLabels() { + props = append(props, build_terraform_labels_field(p, resource, parent)) + } } props = append(props, p) @@ -929,7 +940,7 @@ func build_effective_labels_field(p Property, resource *Resource, parent *Proper description := fmt.Sprintf("All of %s (key/value pairs) present on the resource in GCP, including the %s configured through Terraform, other clients and services.", p.title, p.title) stateSetter := fmt.Sprintf("d.Set(%q, res.%s)", title, p.PackageName) - return Property{ + effectiveLabels := Property{ title: title, Type: p.Type, Description: description, @@ -937,6 +948,30 @@ func build_effective_labels_field(p Property, resource *Resource, parent *Proper parent: parent, Optional: false, Computed: true, + ForceNew: p.ForceNew, // Add ForceNew property if labels field has it + PackageName: p.PackageName, + Settable: true, + StateSetter: &stateSetter, + } + + stateGetter := effectiveLabels.DefaultStateGetter() + effectiveLabels.StateGetter = &stateGetter + return effectiveLabels +} + +func build_terraform_labels_field(p Property, resource *Resource, parent *Property) Property { + title := fmt.Sprintf("terraform_%s", p.title) + description := fmt.Sprintf("The combination of %s configured directly on the resource and default %s configured on the provider.", p.title, p.title) + stateSetter := fmt.Sprintf("d.Set(%q, flatten%sTerraform%s(res.%s, d))", title, p.resource.PathType(), p.PackagePath(), p.PackageName) + + return Property{ + title: title, + Type: p.Type, + Description: description, + resource: resource, + parent: parent, + Computed: true, + PackageName: p.PackageName, StateSetter: &stateSetter, } } diff --git a/tpgtools/resource.go b/tpgtools/resource.go index 1e6f6e7a1498..26c94420ef45 100644 --- a/tpgtools/resource.go +++ b/tpgtools/resource.go @@ -586,6 +586,14 @@ func createResource(schema *openapi.Schema, info *openapi.Info, typeFetcher *Typ res.CustomizeDiff = cdiff.Functions } + if res.HasLabels() { + res.CustomizeDiff = append(res.CustomizeDiff, "tpgresource.SetLabelsDiff") + } + + if res.HasAnnotations() { + res.CustomizeDiff = append(res.CustomizeDiff, "tpgresource.SetAnnotationsDiff") + } + // ListFields if parameters, ok := typeFetcher.doc.Paths["list"]; ok { for _, param := range parameters.Parameters { @@ -835,7 +843,7 @@ func (r *Resource) loadHandWrittenSamples() []Sample { // During importing, as the configuration is unavailableafter, the "labels" and "annotations" fields in the state will be empty. // So add the "labels" and the "annotations" fields to the ImportStateVerifyIgnore list. if r.HasLabels() { - sample.IgnoreRead = append(sample.IgnoreRead, "labels") + sample.IgnoreRead = append(sample.IgnoreRead, "labels", "terraform_labels") } if r.HasAnnotations() { @@ -930,10 +938,10 @@ func (r *Resource) loadDCLSamples() []Sample { sample.TestSlug = RenderedString(sampleNameToTitleCase(*sample.Name).titlecase()) // The "labels" and "annotations" fields in the state are decided by the configuration. - // During importing, as the configuration is unavailableafter, the "labels" and "annotations" fields in the state will be empty. + // During importing, as the configuration is unavailable, the "labels" and "annotations" fields in the state will be empty. // So add the "labels" and the "annotations" fields to the ImportStateVerifyIgnore list. if r.HasLabels() { - sample.IgnoreRead = append(sample.IgnoreRead, "labels") + sample.IgnoreRead = append(sample.IgnoreRead, "labels", "terraform_labels") } if r.HasAnnotations() { diff --git a/tpgtools/templates/resource.go.tmpl b/tpgtools/templates/resource.go.tmpl index a3f10f2db10b..db1eeb4d6aea 100644 --- a/tpgtools/templates/resource.go.tmpl +++ b/tpgtools/templates/resource.go.tmpl @@ -723,7 +723,22 @@ func flatten{{$.PathType}}Labels(v map[string]string, d *schema.ResourceData) in transformed := make(map[string]interface{}) if l, ok := d.Get("labels").(map[string]interface{}); ok { for k, _ := range l { - transformed[k] = l[k] + transformed[k] = v[k] + } + } + + return transformed +} + +func flatten{{$.PathType}}TerraformLabels(v map[string]string, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + + transformed := make(map[string]interface{}) + if l, ok := d.Get("terraform_labels").(map[string]interface{}); ok { + for k, _ := range l { + transformed[k] = v[k] } } @@ -740,7 +755,7 @@ func flatten{{$.PathType}}Annotations(v map[string]string, d *schema.ResourceDat transformed := make(map[string]interface{}) if l, ok := d.Get("annotations").(map[string]interface{}); ok { for k, _ := range l { - transformed[k] = l[k] + transformed[k] = v[k] } } diff --git a/tpgtools/templates/serialization.go.tmpl b/tpgtools/templates/serialization.go.tmpl index 7936e1a0119c..faba0a38cdfc 100644 --- a/tpgtools/templates/serialization.go.tmpl +++ b/tpgtools/templates/serialization.go.tmpl @@ -126,7 +126,7 @@ func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSn func {{ $res.TitleCaseFullName }}{{$version.SerializationSuffix}}AsHCL(r {{$res.Package}}{{$version.SerializationSuffix}}.{{$res.DCLStructName}}, hasGAEquivalent bool) (string, error) { outputConfig := "resource \"{{$res.TerraformName}}\" \"output\" {\n" {{- range $field := $res.Properties}} - {{- if $field.Settable }} + {{- if $field.ShouldShowUpInSamples }} {{- if eq $field.Type.String "TypeString" "TypeInt" "TypeBool" "TypeFloat" }} {{- if $field.Type.IsDateTime }} if !r.{{$field.PackageName}}.IsZero() { From 6b85f73f9852bbb0fe6c619876fe88cad28570f9 Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Wed, 13 Sep 2023 20:40:00 +0000 Subject: [PATCH 059/476] Unset other credentials variables before constructing config (#8935) --- mmv1/third_party/tgc/getconfig_test.go | 35 +++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/mmv1/third_party/tgc/getconfig_test.go b/mmv1/third_party/tgc/getconfig_test.go index 4afa9529d762..d70db6c6ae8c 100644 --- a/mmv1/third_party/tgc/getconfig_test.go +++ b/mmv1/third_party/tgc/getconfig_test.go @@ -16,9 +16,11 @@ type configAttrGetter func(cfg *transport_tpg.Config) string func getCredentials(cfg *transport_tpg.Config) string { return cfg.Credentials } + func getAccessToken(cfg *transport_tpg.Config) string { return cfg.AccessToken } + func getImpersonateServiceAccount(cfg *transport_tpg.Config) string { return cfg.ImpersonateServiceAccount } @@ -29,6 +31,7 @@ func TestNewConfigExtractsEnvVars(t *testing.T) { cases := []struct { name string envKey string + unsetKeys []string // environment variables that must be unset before constructing config envValue string expected string getConfigValue configAttrGetter @@ -43,6 +46,7 @@ func TestNewConfigExtractsEnvVars(t *testing.T) { { name: "GOOGLE_CLOUD_KEYFILE_JSON", envKey: "GOOGLE_CLOUD_KEYFILE_JSON", + unsetKeys: []string{"GOOGLE_CREDENTIALS"}, envValue: "whatever", expected: "whatever", getConfigValue: getCredentials, @@ -50,6 +54,7 @@ func TestNewConfigExtractsEnvVars(t *testing.T) { { name: "GCLOUD_KEYFILE_JSON", envKey: "GCLOUD_KEYFILE_JSON", + unsetKeys: []string{"GOOGLE_CREDENTIALS", "GOOGLE_CLOUD_KEYFILE_JSON"}, envValue: "whatever", expected: "whatever", getConfigValue: getCredentials, @@ -72,7 +77,22 @@ func TestNewConfigExtractsEnvVars(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { + // Store existing state of environment variables. + existingEnv := make(map[string]string, len(c.unsetKeys)+1) + for _, key := range c.unsetKeys { + if originalValue, isSet := os.LookupEnv(key); isSet { + existingEnv[key] = originalValue + // Unset variables that would interfere with test. + err := os.Unsetenv(key) + if err != nil { + t.Fatalf("error unsetting env var %s: %s", key, err) + } + } + } originalValue, isSet := os.LookupEnv(c.envKey) + if isSet { + existingEnv[c.envKey] = originalValue + } err := os.Setenv(c.envKey, c.envValue) if err != nil { t.Fatalf("error setting env var %s=%s: %s", c.envKey, c.envValue, err) @@ -85,17 +105,20 @@ func TestNewConfigExtractsEnvVars(t *testing.T) { assert.Equal(t, c.expected, c.getConfigValue(cfg)) - if isSet { - err = os.Setenv(c.envKey, originalValue) - if err != nil { - t.Fatalf("error setting env var %s=%s: %s", c.envKey, originalValue, err) - } - } else { + // Restore previous states of environment variables. + if !isSet { + // c.envKey was previously unset. err = os.Unsetenv(c.envKey) if err != nil { t.Fatalf("error unsetting env var %s: %s", c.envKey, err) } } + for key, value := range existingEnv { + err = os.Setenv(key, value) + if err != nil { + t.Fatalf("error setting env var %s=%s: %s", key, value, err) + } + } }) } } From 1ca641467afd285e682f75a8afa43b35c90ac8b3 Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:43:37 -0700 Subject: [PATCH 060/476] Add sweeper for dataproc_cluster (#8927) --- .../resource_dataproc_cluster_sweeper.go | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster_sweeper.go diff --git a/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster_sweeper.go b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster_sweeper.go new file mode 100644 index 000000000000..ad4927e28a19 --- /dev/null +++ b/mmv1/third_party/terraform/services/dataproc/resource_dataproc_cluster_sweeper.go @@ -0,0 +1,126 @@ +package dataproc + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("DataprocCluster", testSweepDataprocCluster) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepDataprocCluster(region string) error { + resourceName := "DataprocCluster" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://dataproc.googleapis.com/v1/projects/{{project}}/regions/{{region}}/clusters", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["policies"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + var name string + // Id detected in the delete URL, attempt to use id. + if obj["id"] != nil { + name = tpgresource.GetResourceNameFromSelfLink(obj["id"].(string)) + } else if obj["name"] != nil { + name = tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + } else { + log.Printf("[INFO][SWEEPER_LOG] %s resource name and id were nil", resourceName) + return nil + } + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://dataproc.googleapis.com/v1/projects/{{project}}/regions/{{region}}/clusters/{cluster_id}" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} From c8478f3a43b0f3f03542f5427104760eb5fb482c Mon Sep 17 00:00:00 2001 From: Zeleena Kearney <12972510+zeleena@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:29:44 -0700 Subject: [PATCH 061/476] Add new TPUv2 product and VM resource in beta (#8899) * Add new TPUv2 product and VM resource in beta * Add TPUv2 vm full example * Add async operation polling and update API version * Update examples to pass tests * Change example zone to avoid capacity issues during tests on those examples * Hardcode version and accelerator type in to examples since github check values vary from local * Change API version from v2alpha1 to v2, will override to v2alpha1 in the terraform-eap process * Add update test for description --- mmv1/products/tpuv2/Vm.yaml | 90 +++++++++++++++++ mmv1/products/tpuv2/product.yaml | 26 +++++ .../terraform/examples/tpu_v2_vm_basic.tf.erb | 12 +++ .../terraform/examples/tpu_v2_vm_full.tf.erb | 18 ++++ .../terraform/provider/provider.go.erb | 4 + .../data_source_tpu_v2_accelerator_types.go | 93 ++++++++++++++++++ ...ta_source_tpu_v2_accelerator_types_test.go | 68 +++++++++++++ .../data_source_tpu_v2_runtime_versions.go | 93 ++++++++++++++++++ ...ata_source_tpu_v2_runtime_versions_test.go | 68 +++++++++++++ .../tpuv2/resource_tpu_v2_vm_test.go.erb | 98 +++++++++++++++++++ .../d/tpu_v2_accelerator_types.html.markdown | 49 ++++++++++ .../d/tpu_v2_runtime_versions.html.markdown | 45 +++++++++ 12 files changed, 664 insertions(+) create mode 100644 mmv1/products/tpuv2/Vm.yaml create mode 100644 mmv1/products/tpuv2/product.yaml create mode 100644 mmv1/templates/terraform/examples/tpu_v2_vm_basic.tf.erb create mode 100644 mmv1/templates/terraform/examples/tpu_v2_vm_full.tf.erb create mode 100644 mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types.go create mode 100644 mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types_test.go create mode 100644 mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions.go create mode 100644 mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions_test.go create mode 100644 mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb create mode 100644 mmv1/third_party/terraform/website/docs/d/tpu_v2_accelerator_types.html.markdown create mode 100644 mmv1/third_party/terraform/website/docs/d/tpu_v2_runtime_versions.html.markdown diff --git a/mmv1/products/tpuv2/Vm.yaml b/mmv1/products/tpuv2/Vm.yaml new file mode 100644 index 000000000000..9c3aed0c9973 --- /dev/null +++ b/mmv1/products/tpuv2/Vm.yaml @@ -0,0 +1,90 @@ +# 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: 'Vm' +description: | + A Cloud TPU VM instance. +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Official Documentation': 'https://cloud.google.com/tpu/docs/' + api: 'https://cloud.google.com/tpu/docs/reference/rest/v2/projects.locations.nodes' +base_url: projects/{{project}}/locations/{{zone}}/nodes +self_link: projects/{{project}}/locations/{{zone}}/nodes/{{name}} +create_url: projects/{{project}}/locations/{{zone}}/nodes?nodeId={{name}} +update_url: projects/{{project}}/locations/{{zone}}/nodes/{{name}} +update_verb: :PATCH +update_mask: true +autogen_async: true +async: !ruby/object:Api::OpAsync + operation: !ruby/object:Api::OpAsync::Operation + path: 'name' + base_url: '{{op_id}}' + wait_ms: 1000 + result: !ruby/object:Api::OpAsync::Result + path: 'response' + resource_inside_response: true + status: !ruby/object:Api::OpAsync::Status + path: 'done' + complete: true + allowed: + - true + - false + error: !ruby/object:Api::OpAsync::Error + path: 'error' + message: 'message' +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'tpu_v2_vm_basic' + min_version: 'beta' + primary_resource_id: 'tpu' + vars: + vm_name: 'test-tpu' + - !ruby/object:Provider::Terraform::Examples + name: 'tpu_v2_vm_full' + min_version: 'beta' + primary_resource_id: 'tpu' + vars: + vm_name: 'test-tpu' +parameters: + - !ruby/object:Api::Type::String + name: 'zone' + description: | + The GCP location for the TPU. If it is not provided, the provider zone is used. + immutable: true + url_param_only: true + default_from_api: true +properties: + - !ruby/object:Api::Type::String + name: 'name' + required: true + immutable: true + description: | + The immutable name of the TPU. + custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb' + - !ruby/object:Api::Type::String + name: 'runtimeVersion' + required: true + immutable: true + description: | + Runtime version for the TPU. + - !ruby/object:Api::Type::String + name: 'acceleratorType' + immutable: true + default_value: 'v2-8' + description: | + TPU accelerator type for the TPU. If not specified, this defaults to 'v2-8'. + - !ruby/object:Api::Type::String + name: 'description' + description: | + Text description of the TPU. diff --git a/mmv1/products/tpuv2/product.yaml b/mmv1/products/tpuv2/product.yaml new file mode 100644 index 000000000000..20dded6c52e6 --- /dev/null +++ b/mmv1/products/tpuv2/product.yaml @@ -0,0 +1,26 @@ +# 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::Product +name: TpuV2 +display_name: Cloud TPU v2 +versions: + - !ruby/object:Api::Product::Version + name: beta + base_url: https://tpu.googleapis.com/v2/ +scopes: + - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud TPU API + url: https://console.cloud.google.com/apis/library/tpu.googleapis.com/ diff --git a/mmv1/templates/terraform/examples/tpu_v2_vm_basic.tf.erb b/mmv1/templates/terraform/examples/tpu_v2_vm_basic.tf.erb new file mode 100644 index 000000000000..9888f0e30cbb --- /dev/null +++ b/mmv1/templates/terraform/examples/tpu_v2_vm_basic.tf.erb @@ -0,0 +1,12 @@ +data "google_tpu_v2_runtime_versions" "available" { + provider = google-beta +} + +resource "google_tpu_v2_vm" "<%= ctx[:primary_resource_id] %>" { + provider = google-beta + + name = "<%= ctx[:vars]["vm_name"] %>" + zone = "us-central1-c" + + runtime_version = "tpu-vm-tf-2.13.0" +} diff --git a/mmv1/templates/terraform/examples/tpu_v2_vm_full.tf.erb b/mmv1/templates/terraform/examples/tpu_v2_vm_full.tf.erb new file mode 100644 index 000000000000..a7d45bd80ce8 --- /dev/null +++ b/mmv1/templates/terraform/examples/tpu_v2_vm_full.tf.erb @@ -0,0 +1,18 @@ +data "google_tpu_v2_runtime_versions" "available" { + provider = google-beta +} + +data "google_tpu_v2_accelerator_types" "available" { + provider = google-beta +} + +resource "google_tpu_v2_vm" "<%= ctx[:primary_resource_id] %>" { + provider = google-beta + + name = "<%= ctx[:vars]["vm_name"] %>" + zone = "us-central1-c" + description = "Text description of the TPU." + + runtime_version = "tpu-vm-tf-2.13.0" + accelerator_type = "v2-8" +} diff --git a/mmv1/third_party/terraform/provider/provider.go.erb b/mmv1/third_party/terraform/provider/provider.go.erb index 9fd136341311..500d9cdded3c 100644 --- a/mmv1/third_party/terraform/provider/provider.go.erb +++ b/mmv1/third_party/terraform/provider/provider.go.erb @@ -345,6 +345,10 @@ func DatasourceMapWithErrors() (map[string]*schema.Resource, error) { "google_tags_tag_key": tags.DataSourceGoogleTagsTagKey(), "google_tags_tag_value": tags.DataSourceGoogleTagsTagValue(), "google_tpu_tensorflow_versions": tpu.DataSourceTpuTensorflowVersions(), + <% unless version == 'ga' -%> + "google_tpu_v2_runtime_versions": tpuv2.DataSourceTpuV2RuntimeVersions(), + "google_tpu_v2_accelerator_types": tpuv2.DataSourceTpuV2AcceleratorTypes(), + <% end -%> "google_vpc_access_connector": vpcaccess.DataSourceVPCAccessConnector(), "google_redis_instance": redis.DataSourceGoogleRedisInstance(), "google_vertex_ai_index": vertexai.DataSourceVertexAIIndex(), diff --git a/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types.go b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types.go new file mode 100644 index 000000000000..a1ce5bbecf99 --- /dev/null +++ b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types.go @@ -0,0 +1,93 @@ +package tpuv2 + +import ( + "fmt" + "log" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func DataSourceTpuV2AcceleratorTypes() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTpuV2AcceleratorTypesRead, + Schema: map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "zone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "types": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceTpuV2AcceleratorTypesRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return err + } + + zone, err := tpgresource.GetZone(d, config) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{TpuV2BasePath}}projects/{{project}}/locations/{{zone}}/acceleratorTypes") + if err != nil { + return err + } + + typesRaw, err := tpgresource.PaginatedListRequest(project, url, userAgent, config, flattenTpuV2AcceleratorTypes) + if err != nil { + return fmt.Errorf("error listing TPU v2 accelerator types: %s", err) + } + + types := make([]string, len(typesRaw)) + for i, typeRaw := range typesRaw { + types[i] = typeRaw.(string) + } + sort.Strings(types) + + log.Printf("[DEBUG] Received Google TPU v2 accelerator types: %q", types) + + if err := d.Set("types", types); err != nil { + return fmt.Errorf("error setting types: %s", err) + } + if err := d.Set("zone", zone); err != nil { + return fmt.Errorf("error setting zone: %s", err) + } + if err := d.Set("project", project); err != nil { + return fmt.Errorf("error setting project: %s", err) + } + d.SetId(fmt.Sprintf("projects/%s/zones/%s", project, zone)) + + return nil +} + +func flattenTpuV2AcceleratorTypes(resp map[string]interface{}) []interface{} { + typeObjList := resp["acceleratorTypes"].([]interface{}) + types := make([]interface{}, len(typeObjList)) + for i, typ := range typeObjList { + typeObj := typ.(map[string]interface{}) + types[i] = typeObj["type"] + } + return types +} diff --git a/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types_test.go b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types_test.go new file mode 100644 index 000000000000..58e3f6af577a --- /dev/null +++ b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_accelerator_types_test.go @@ -0,0 +1,68 @@ +package tpuv2_test + +import ( + "errors" + "fmt" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccTpuV2AcceleratorTypes_basic(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccTpuV2AcceleratorTypesConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckTpuV2AcceleratorTypes("data.google_tpu_v2_accelerator_types.available"), + ), + }, + }, + }) +} + +func testAccCheckTpuV2AcceleratorTypes(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("can't find TPU v2 accelerator types data source: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("data source id not set") + } + + count, ok := rs.Primary.Attributes["types.#"] + if !ok { + return errors.New("can't find 'types' attribute") + } + + cnt, err := strconv.Atoi(count) + if err != nil { + return errors.New("failed to read number of types") + } + if cnt < 2 { + return fmt.Errorf("expected at least 2 types, received %d, this is most likely a bug", cnt) + } + + for i := 0; i < cnt; i++ { + idx := fmt.Sprintf("types.%d", i) + _, ok := rs.Primary.Attributes[idx] + if !ok { + return fmt.Errorf("expected %q, type not found", idx) + } + } + return nil + } +} + +const testAccTpuV2AcceleratorTypesConfig = ` +data "google_tpu_v2_accelerator_types" "available" {} +` diff --git a/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions.go b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions.go new file mode 100644 index 000000000000..373379534a87 --- /dev/null +++ b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions.go @@ -0,0 +1,93 @@ +package tpuv2 + +import ( + "fmt" + "log" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func DataSourceTpuV2RuntimeVersions() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTpuV2RuntimeVersionsRead, + Schema: map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "zone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "versions": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceTpuV2RuntimeVersionsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return err + } + + zone, err := tpgresource.GetZone(d, config) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{TpuV2BasePath}}projects/{{project}}/locations/{{zone}}/runtimeVersions") + if err != nil { + return err + } + + versionsRaw, err := tpgresource.PaginatedListRequest(project, url, userAgent, config, flattenTpuV2RuntimeVersions) + if err != nil { + return fmt.Errorf("error listing TPU v2 runtime versions: %s", err) + } + + versions := make([]string, len(versionsRaw)) + for i, ver := range versionsRaw { + versions[i] = ver.(string) + } + sort.Strings(versions) + + log.Printf("[DEBUG] Received Google TPU v2 runtime versions: %q", versions) + + if err := d.Set("versions", versions); err != nil { + return fmt.Errorf("error setting versions: %s", err) + } + if err := d.Set("zone", zone); err != nil { + return fmt.Errorf("error setting zone: %s", err) + } + if err := d.Set("project", project); err != nil { + return fmt.Errorf("error setting project: %s", err) + } + d.SetId(fmt.Sprintf("projects/%s/zones/%s", project, zone)) + + return nil +} + +func flattenTpuV2RuntimeVersions(resp map[string]interface{}) []interface{} { + verObjList := resp["runtimeVersions"].([]interface{}) + versions := make([]interface{}, len(verObjList)) + for i, v := range verObjList { + verObj := v.(map[string]interface{}) + versions[i] = verObj["version"] + } + return versions +} diff --git a/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions_test.go b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions_test.go new file mode 100644 index 000000000000..558c0f95ce53 --- /dev/null +++ b/mmv1/third_party/terraform/services/tpuv2/data_source_tpu_v2_runtime_versions_test.go @@ -0,0 +1,68 @@ +package tpuv2_test + +import ( + "errors" + "fmt" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccTpuV2RuntimeVersions_basic(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccTpuV2RuntimeVersionsConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckTpuV2RuntimeVersions("data.google_tpu_v2_runtime_versions.available"), + ), + }, + }, + }) +} + +func testAccCheckTpuV2RuntimeVersions(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("can't find TPU v2 runtime versions data source: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("data source id not set") + } + + count, ok := rs.Primary.Attributes["versions.#"] + if !ok { + return errors.New("can't find 'versions' attribute") + } + + cnt, err := strconv.Atoi(count) + if err != nil { + return errors.New("failed to read number of versions") + } + if cnt < 2 { + return fmt.Errorf("expected at least 2 versions, received %d, this is most likely a bug", cnt) + } + + for i := 0; i < cnt; i++ { + idx := fmt.Sprintf("versions.%d", i) + _, ok := rs.Primary.Attributes[idx] + if !ok { + return fmt.Errorf("expected %q, version not found", idx) + } + } + return nil + } +} + +const testAccTpuV2RuntimeVersionsConfig = ` +data "google_tpu_v2_runtime_versions" "available" {} +` diff --git a/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb b/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb new file mode 100644 index 000000000000..6fbb45c2f5b3 --- /dev/null +++ b/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb @@ -0,0 +1,98 @@ +<% autogen_exception -%> +package tpuv2_test + +<% unless version == 'ga' -%> +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" +) + +func TestAccTpuV2Vm_update(t *testing.T) { + t.Parallel() + + randomSuffix := acctest.RandString(t, 10) + context := map[string]interface{}{ + "random_suffix": randomSuffix, + "description": "Old description original context", + } + updatedContext := map[string]interface{}{ + "random_suffix": randomSuffix, + "description": "New description updated context", + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t), + CheckDestroy: testAccCheckTpuV2VmDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccTpuV2Vm_full(context), + }, + { + ResourceName: "google_tpu_v2_vm.tpu", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"zone"}, + }, + { + Config: testAccTpuV2Vm_update(updatedContext), + }, + { + ResourceName: "google_tpu_v2_vm.tpu", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"zone"}, + }, + }, + }) +} + +func testAccTpuV2Vm_full(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_tpu_v2_runtime_versions" "available" { + provider = google-beta +} + +data "google_tpu_v2_accelerator_types" "available" { + provider = google-beta +} + +resource "google_tpu_v2_vm" "tpu" { + provider = google-beta + + name = "tf-test-test-tpu%{random_suffix}" + zone = "us-central1-c" + description = "%{description}" + + runtime_version = "tpu-vm-tf-2.13.0" + accelerator_type = "v2-8" +} +`, context) +} + +func testAccTpuV2Vm_update(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_tpu_v2_runtime_versions" "available" { + provider = google-beta +} + +data "google_tpu_v2_accelerator_types" "available" { + provider = google-beta +} + +resource "google_tpu_v2_vm" "tpu" { + provider = google-beta + + name = "tf-test-test-tpu%{random_suffix}" + zone = "us-central1-c" + description = "%{description}" + + runtime_version = "tpu-vm-tf-2.13.0" + accelerator_type = "v2-8" +} +`, context) +} +<% end -%> diff --git a/mmv1/third_party/terraform/website/docs/d/tpu_v2_accelerator_types.html.markdown b/mmv1/third_party/terraform/website/docs/d/tpu_v2_accelerator_types.html.markdown new file mode 100644 index 000000000000..f953bcdc7aac --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/d/tpu_v2_accelerator_types.html.markdown @@ -0,0 +1,49 @@ +--- +subcategory: "Cloud TPU v2" +description: |- + Get available accelerator types. +--- + +# google\_tpu\_v2\_accelerator\_types + +Get accelerator types available for a project. For more information see the [official documentation](https://cloud.google.com/tpu/docs/) and [API](https://cloud.google.com/tpu/docs/reference/rest/v2/projects.locations.acceleratorTypes). + +## Example Usage + +```hcl +data "google_tpu_v2_accelerator_types" "available" { +} +``` + +## Example Usage: Configure Basic TPU VM with available type + +```hcl +data "google_tpu_v2_accelerator_types" "available" { +} + +data "google_tpu_v2_runtime_versions" "available" { +} + +resource "google_tpu_v2_vm" "tpu" { + name = "test-tpu" + zone = "us-central1-b" + runtime_version = data.google_tpu_v2_runtime_versions.available.versions[0] + accelerator_type = data.google_tpu_v2_accelerator_types.available.types[0] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `project` - (Optional) The project to list types for. If it + is not provided, the provider project is used. + +* `zone` - (Optional) The zone to list types for. If it + is not provided, the provider zone is used. + +## Attributes Reference + +The following attributes are exported: + +* `types` - The list of accelerator types available for the given project and zone. diff --git a/mmv1/third_party/terraform/website/docs/d/tpu_v2_runtime_versions.html.markdown b/mmv1/third_party/terraform/website/docs/d/tpu_v2_runtime_versions.html.markdown new file mode 100644 index 000000000000..b4d6358b2f79 --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/d/tpu_v2_runtime_versions.html.markdown @@ -0,0 +1,45 @@ +--- +subcategory: "Cloud TPU v2" +description: |- + Get available runtime versions. +--- + +# google\_tpu\_v2\_runtime\_versions + +Get runtime versions available for a project. For more information see the [official documentation](https://cloud.google.com/tpu/docs/) and [API](https://cloud.google.com/tpu/docs/reference/rest/v2/projects.locations.runtimeVersions). + +## Example Usage + +```hcl +data "google_tpu_v2_runtime_versions" "available" { +} +``` + +## Example Usage: Configure Basic TPU VM with available version + +```hcl +data "google_tpu_v2_runtime_versions" "available" { +} + +resource "google_tpu_v2_vm" "tpu" { + name = "test-tpu" + zone = "us-central1-b" + runtime_version = data.google_tpu_v2_runtime_versions.available.versions[0] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `project` - (Optional) The project to list versions for. If it + is not provided, the provider project is used. + +* `zone` - (Optional) The zone to list versions for. If it + is not provided, the provider zone is used. + +## Attributes Reference + +The following attributes are exported: + +* `versions` - The list of runtime versions available for the given project and zone. From ffda75272f70e04797dfa725baf17e6637800033 Mon Sep 17 00:00:00 2001 From: Shuya Ma Date: Wed, 13 Sep 2023 20:47:59 -0700 Subject: [PATCH 062/476] resolve more conflicts --- .../services/bigquery/resource_bigquery_table_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go index 046b41bf9e74..cc5f910604d3 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go @@ -633,7 +633,6 @@ func TestAccBigQueryTable_MaterializedView_WithView(t *testing.T) { { Config: testAccBigQueryTableWithMatViewAndView(datasetID, tableID, materializedViewID, query), ExpectError: regexp.MustCompile("\"materialized_view\": conflicts with view"), ->>>>>>> FEATURE-BRANCH-major-release-5.0.0 }, }, }) @@ -3552,7 +3551,7 @@ func testAccBigQueryTableTableConstraintsUpdate(projectID, datasetID, tableID_pk } `, datasetID, tableID_pk, projectID, projectID, tableID_fk) } - + func testAccBigQueryTableWithSchema(datasetID, tableID, schema string) string { return fmt.Sprintf(` resource "google_bigquery_dataset" "test" { From 6f6770b8280cfe329542cc5ba18a3066457549bc Mon Sep 17 00:00:00 2001 From: Jared Date: Thu, 14 Sep 2023 07:05:54 -0700 Subject: [PATCH 063/476] Artifact Registry: implement VPC SC Config (#8787) * Artifact Registry: implement VPC SC Config * Altering behavior from reset resource to simply drop resource * removing skip_test * re-adding skip_test since organization-level resources are out of scope for testing --- .../artifactregistry/VPCSCConfig.yaml | 70 +++++++++++++++++++ .../artifact_registry_vpcsc_config.tf.erb | 6 ++ 2 files changed, 76 insertions(+) create mode 100644 mmv1/products/artifactregistry/VPCSCConfig.yaml create mode 100644 mmv1/templates/terraform/examples/artifact_registry_vpcsc_config.tf.erb diff --git a/mmv1/products/artifactregistry/VPCSCConfig.yaml b/mmv1/products/artifactregistry/VPCSCConfig.yaml new file mode 100644 index 000000000000..6751669c1bb3 --- /dev/null +++ b/mmv1/products/artifactregistry/VPCSCConfig.yaml @@ -0,0 +1,70 @@ +# 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: 'VPCSCConfig' +description: |- + The Artifact Registry VPC SC config that applies to a Project. +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/artifact-registry/docs/reference/rest/v1/VPCSCConfig' +min_version: beta +docs: !ruby/object:Provider::Terraform::Docs + note: |- + VPC SC configs are automatically created for a given location. Creating a + resource of this type will acquire and update the resource that already + exists at the location. Deleting this resource will remove the config from + your Terraform state but leave the resource as is. +base_url: 'projects/{{project}}/locations/{{location}}/vpcscConfig' +self_link: 'projects/{{project}}/locations/{{location}}/vpcscConfig' +create_url: 'projects/{{project}}/locations/{{location}}/vpcscConfig' +create_verb: :PATCH +update_verb: :PATCH +skip_delete: true +examples: + - !ruby/object:Provider::Terraform::Examples + # Requires VPC SC Policy configured on organization + skip_test: true + name: 'artifact_registry_vpcsc_config' + primary_resource_id: 'my-config' +autogen_async: false +async: !ruby/object:Api::OpAsync + actions: [] + # necessary to compile + operation: !ruby/object:Api::OpAsync::Operation + base_url: '{{op_id}}' +custom_code: !ruby/object:Provider::Terraform::CustomCode + encoder: templates/terraform/encoders/location_from_region.go.erb +parameters: + - !ruby/object:Api::Type::String + name: location + required: false + immutable: true + url_param_only: true + default_from_api: true + description: | + The name of the location this config is located in. + - !ruby/object:Api::Type::String + name: name + output: true + description: |- + The name of the project's VPC SC Config. + Always of the form: projects/{project}/location/{location}/vpcscConfig +properties: + - !ruby/object:Api::Type::Enum + name: vpcscPolicy + min_version: beta + description: |- + The VPC SC policy for project and location. + values: + - :DENY + - :ALLOW diff --git a/mmv1/templates/terraform/examples/artifact_registry_vpcsc_config.tf.erb b/mmv1/templates/terraform/examples/artifact_registry_vpcsc_config.tf.erb new file mode 100644 index 000000000000..171b8b725d61 --- /dev/null +++ b/mmv1/templates/terraform/examples/artifact_registry_vpcsc_config.tf.erb @@ -0,0 +1,6 @@ +resource "google_artifact_registry_vpcsc_config" "<%= ctx[:primary_resource_id] %>" { + provider = google-beta + location = "us-central1" + vpcsc_policy = "ALLOW" +} + From 3b4a1438b615771e95bbd6cb794d453c48384d86 Mon Sep 17 00:00:00 2001 From: "Bob \"Wombat\" Hogg" Date: Thu, 14 Sep 2023 10:53:52 -0400 Subject: [PATCH 064/476] docs: Clarify naming conventions for deletion_protection (#8944) --- docs/content/best-practices/_index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/content/best-practices/_index.md b/docs/content/best-practices/_index.md index 192af1b155a4..e0b4b9a2c3ea 100644 --- a/docs/content/best-practices/_index.md +++ b/docs/content/best-practices/_index.md @@ -23,9 +23,10 @@ In complex cases, it is better to mark the field `ForceNew` to ensure that users Some resources, such as databases, have a significant risk of unrecoverable data loss if the resource is accidentally deleted due to a change to a ForceNew field. For these resources, the best practice is to add a `deletion_protection` field that defaults to `true`, which prevents the resource from being deleted if enabled. Although it is a small breaking change, for users, the benefits of `deletion_protection` defaulting to `true` outweigh the cost. -APIs also sometimes add `deletion_protection` fields, which will generally default to `false` for backwards-compatibility reasons. Any `deletion_protection` API field added to an existing Terraform resource must match the API default initially. The default may be set to `true` in the next major release. For new Terraform resources, any `deletion_protection` field should default to `true` in Terraform regardless of the API default. +APIs also sometimes add `deletion_protection` fields, which will generally default to `false` for backwards-compatibility reasons. Any `deletion_protection` API field added to an existing Terraform resource must match the API default initially. The default may be set to `true` in the next major release. For new Terraform resources, any `deletion_protection` field should default to `true` in Terraform regardless of the API default. When creating the corresponding Terraform field, the name +should match the API field name (i.e. it need not literally be named `deletion_protection` if the API uses something different) and should be the same field type (example: if the API field is an enum, so should the Terraform field). -A resource can have up to two `deletion_protection` fields (with different names): one that represents a field in the API, and one that is only in Terraform. This could happen because the API added its field after `deletion_protection` already existed in Terraform; it could also happen because a separate field was added in Terraform to make sure that `deletion_protection` is enabled by default. In either case, they should be reconciled into a single field (that defaults to `true`) in the next major release. +A resource can have up to two `deletion_protection` fields (with different names): one that represents a field in the API, and one that is only in Terraform. This could happen because the API added its field after `deletion_protection` already existed in Terraform; it could also happen because a separate field was added in Terraform to make sure that `deletion_protection` is enabled by default. In either case, they should be reconciled into a single field (that defaults to enabled and whose name matches the API field) in the next major release. Resources that do not have a significant risk of unrecoverable data loss or similar critical concern will not be given `deletion_protection` fields. From 98a2f7047061f44e601405ecd31cdbf76f13f5a5 Mon Sep 17 00:00:00 2001 From: pokutuna Date: Fri, 15 Sep 2023 01:27:09 +0900 Subject: [PATCH 065/476] Fix id validation for custom service and SLO to match what's actually usable (#8939) * Fix slo_id pattern in google_monitoring_slo * Fix servie_id pattern in google_monitoring_custom_service --- mmv1/products/monitoring/Service.yaml | 2 +- mmv1/products/monitoring/Slo.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mmv1/products/monitoring/Service.yaml b/mmv1/products/monitoring/Service.yaml index a6d1255c8fcb..4624cafcd416 100644 --- a/mmv1/products/monitoring/Service.yaml +++ b/mmv1/products/monitoring/Service.yaml @@ -54,7 +54,7 @@ parameters: custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb default_from_api: true validation: !ruby/object:Provider::Terraform::Validation - regex: '^[a-z0-9\-]+$' + regex: '^[a-zA-Z0-9\-_:.]+$' properties: - !ruby/object:Api::Type::String name: name diff --git a/mmv1/products/monitoring/Slo.yaml b/mmv1/products/monitoring/Slo.yaml index 1f29828e282c..b29c5b7a1304 100644 --- a/mmv1/products/monitoring/Slo.yaml +++ b/mmv1/products/monitoring/Slo.yaml @@ -95,7 +95,7 @@ parameters: custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb default_from_api: true validation: !ruby/object:Provider::Terraform::Validation - regex: '^[a-z0-9\-]+$' + regex: '^[a-zA-Z0-9\-_:.]+$' properties: - !ruby/object:Api::Type::String name: name From 0662994fadc8857001b02019fb4fa2fd178b60af Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Thu, 14 Sep 2023 11:49:12 -0500 Subject: [PATCH 066/476] Remove api_reference (apis_required) (#8947) --- mmv1/api/product.rb | 6 ---- mmv1/api/product/api_reference.rb | 30 ------------------- mmv1/products/accessapproval/product.yaml | 4 --- mmv1/products/alloydb/product.yaml | 4 --- mmv1/products/apigee/product.yaml | 4 --- mmv1/products/appengine/product.yaml | 4 --- mmv1/products/artifactregistry/product.yaml | 4 --- mmv1/products/backupdr/product.yaml | 4 --- mmv1/products/beyondcorp/product.yaml | 4 --- mmv1/products/biglake/product.yaml | 4 --- mmv1/products/bigquery/product.yaml | 4 --- .../bigqueryanalyticshub/product.yaml | 4 --- mmv1/products/bigqueryconnection/product.yaml | 4 --- mmv1/products/bigquerydatapolicy/product.yaml | 4 --- .../bigquerydatatransfer/product.yaml | 4 --- .../products/bigqueryreservation/product.yaml | 4 --- mmv1/products/bigtable/product.yaml | 4 --- mmv1/products/billing/product.yaml | 4 --- mmv1/products/billingbudget/product.yaml | 4 --- mmv1/products/certificatemanager/product.yaml | 4 --- mmv1/products/cloudasset/product.yaml | 4 --- mmv1/products/cloudbuild/product.yaml | 4 --- mmv1/products/cloudbuildv2/product.yaml | 4 --- mmv1/products/cloudfunctions/product.yaml | 4 --- mmv1/products/cloudfunctions2/product.yaml | 4 --- mmv1/products/cloudidentity/product.yaml | 4 --- mmv1/products/cloudids/product.yaml | 4 --- mmv1/products/cloudrunv2/product.yaml | 4 --- mmv1/products/cloudscheduler/product.yaml | 4 --- mmv1/products/cloudtasks/product.yaml | 4 --- mmv1/products/compute/product.yaml | 4 --- .../databasemigrationservice/product.yaml | 4 --- mmv1/products/datacatalog/product.yaml | 4 --- mmv1/products/datafusion/product.yaml | 4 --- mmv1/products/dataplex/product.yaml | 4 --- mmv1/products/dataproc/product.yaml | 4 --- mmv1/products/datastore/product.yaml | 4 --- mmv1/products/datastream/product.yaml | 4 --- mmv1/products/deploymentmanager/product.yaml | 4 --- mmv1/products/dialogflow/product.yaml | 4 --- mmv1/products/dialogflowcx/product.yaml | 4 --- mmv1/products/dns/product.yaml | 4 --- mmv1/products/documentai/product.yaml | 4 --- .../products/documentaiwarehouse/product.yaml | 4 --- mmv1/products/essentialcontacts/product.yaml | 4 --- mmv1/products/firebasedatabase/product.yaml | 4 --- mmv1/products/firebaseextensions/product.yaml | 4 --- mmv1/products/firestore/product.yaml | 4 --- mmv1/products/gkebackup/product.yaml | 4 --- mmv1/products/gkehub/product.yaml | 4 --- mmv1/products/gkehub2/product.yaml | 4 --- mmv1/products/gkeonprem/product.yaml | 4 --- mmv1/products/healthcare/product.yaml | 4 --- mmv1/products/iam2/product.yaml | 4 --- mmv1/products/iambeta/product.yaml | 4 --- mmv1/products/iamworkforcepool/product.yaml | 4 --- mmv1/products/iap/product.yaml | 4 --- mmv1/products/identityplatform/product.yaml | 4 --- mmv1/products/kms/product.yaml | 4 --- mmv1/products/logging/product.yaml | 4 --- mmv1/products/looker/product.yaml | 4 --- mmv1/products/metastore/product.yaml | 4 --- mmv1/products/mlengine/product.yaml | 4 --- mmv1/products/monitoring/product.yaml | 4 --- .../products/networkconnectivity/product.yaml | 5 ---- mmv1/products/networkmanagement/product.yaml | 4 --- mmv1/products/networksecurity/product.yaml | 4 --- mmv1/products/networkservices/product.yaml | 4 --- mmv1/products/notebooks/product.yaml | 4 --- mmv1/products/orgpolicy/product.yaml | 4 --- mmv1/products/osconfig/product.yaml | 4 --- mmv1/products/oslogin/product.yaml | 4 --- mmv1/products/privateca/product.yaml | 4 --- mmv1/products/publicca/product.yaml | 4 --- mmv1/products/pubsub/product.yaml | 4 --- mmv1/products/pubsublite/product.yaml | 4 --- mmv1/products/resourcemanager/product.yaml | 4 --- mmv1/products/runtimeconfig/product.yaml | 4 --- mmv1/products/secretmanager/product.yaml | 4 --- mmv1/products/securityscanner/product.yaml | 4 --- mmv1/products/servicedirectory/product.yaml | 4 --- mmv1/products/servicemanagement/product.yaml | 4 --- mmv1/products/serviceusage/product.yaml | 4 --- mmv1/products/sourcerepo/product.yaml | 4 --- mmv1/products/spanner/product.yaml | 4 --- mmv1/products/sql/product.yaml | 4 --- mmv1/products/storage/product.yaml | 4 --- mmv1/products/storageinsights/product.yaml | 7 ----- mmv1/products/storagetransfer/product.yaml | 4 --- mmv1/products/vmwareengine/product.yaml | 4 --- mmv1/products/vpcaccess/product.yaml | 4 --- mmv1/products/workflows/product.yaml | 4 --- mmv1/products/workstations/product.yaml | 4 --- 93 files changed, 404 deletions(-) delete mode 100644 mmv1/api/product/api_reference.rb diff --git a/mmv1/api/product.rb b/mmv1/api/product.rb index 2faca615f254..e5964f986348 100644 --- a/mmv1/api/product.rb +++ b/mmv1/api/product.rb @@ -12,7 +12,6 @@ # limitations under the License. require 'api/object' -require 'api/product/api_reference' require 'api/product/version' require 'google/logger' require 'compile/core' @@ -52,10 +51,6 @@ class Product < Api::Object::Named # failures on operation_get. see github.com/hashicorp/terraform-provider-google/issues/9489 attr_reader :operation_retry - # The APIs required to be enabled for this product. - # Usually just the product's API - attr_reader :apis_required - attr_reader :async attr_reader :legacy_name @@ -75,7 +70,6 @@ def validate check :display_name, type: String check :objects, type: Array, item_type: Api::Resource check :scopes, type: Array, item_type: String, required: true - check :apis_required, type: Array, item_type: Api::Product::ApiReference check :operation_retry, type: String check :async, type: Api::Async diff --git a/mmv1/api/product/api_reference.rb b/mmv1/api/product/api_reference.rb deleted file mode 100644 index aae8278f2438..000000000000 --- a/mmv1/api/product/api_reference.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2019 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. - -require 'api/object' - -module Api - class Product < Api::Object::Named - # Represents any APIs that are required to be enabled to use this product - class ApiReference < Api::Object - attr_reader :name - attr_reader :url - - def validate - super - check :name, type: String, required: true - check :url, type: String, required: true - end - end - end -end diff --git a/mmv1/products/accessapproval/product.yaml b/mmv1/products/accessapproval/product.yaml index 70df0a4a85f0..ec7d98243638 100644 --- a/mmv1/products/accessapproval/product.yaml +++ b/mmv1/products/accessapproval/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://accessapproval.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Access Approval - url: https://console.cloud.google.com/apis/library/accessapproval.googleapis.com/ diff --git a/mmv1/products/alloydb/product.yaml b/mmv1/products/alloydb/product.yaml index dd03681b3583..b9f45eba5d98 100644 --- a/mmv1/products/alloydb/product.yaml +++ b/mmv1/products/alloydb/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://alloydb.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity -apis_required: - - !ruby/object:Api::Product::ApiReference - name: AlloyDB API - url: https://console.cloud.google.com/apis/library/alloydb.googleapis.com diff --git a/mmv1/products/apigee/product.yaml b/mmv1/products/apigee/product.yaml index b5187a753967..4f6c7104702f 100644 --- a/mmv1/products/apigee/product.yaml +++ b/mmv1/products/apigee/product.yaml @@ -27,7 +27,3 @@ versions: base_url: https://apigee.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Apigee API - url: https://console.cloud.google.com/apis/library/apigee.googleapis.com/ diff --git a/mmv1/products/appengine/product.yaml b/mmv1/products/appengine/product.yaml index 699ca84efae5..4c091be92ae5 100644 --- a/mmv1/products/appengine/product.yaml +++ b/mmv1/products/appengine/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://appengine.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: App Engine Admin API - url: https://console.cloud.google.com/apis/library/appengine.googleapis.com/ diff --git a/mmv1/products/artifactregistry/product.yaml b/mmv1/products/artifactregistry/product.yaml index e7eb589a7f91..068579383829 100644 --- a/mmv1/products/artifactregistry/product.yaml +++ b/mmv1/products/artifactregistry/product.yaml @@ -23,10 +23,6 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://artifactregistry.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Artifact Registry API - url: https://console.cloud.google.com/apis/library/artifactregistry.googleapis.com/ async: !ruby/object:Api::OpAsync actions: ['create', 'delete'] operation: !ruby/object:Api::OpAsync::Operation diff --git a/mmv1/products/backupdr/product.yaml b/mmv1/products/backupdr/product.yaml index 43ddaff88eb9..2156cac27c3b 100644 --- a/mmv1/products/backupdr/product.yaml +++ b/mmv1/products/backupdr/product.yaml @@ -20,10 +20,6 @@ versions: - !ruby/object:Api::Product::Version name: beta base_url: https://backupdr.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Backup and DR API - url: https://console.cloud.google.com/apis/library/backupdr.googleapis.com/ async: !ruby/object:Api::OpAsync actions: ['create', 'delete'] operation: !ruby/object:Api::OpAsync::Operation diff --git a/mmv1/products/beyondcorp/product.yaml b/mmv1/products/beyondcorp/product.yaml index eea11e715b7c..39be52f97c04 100644 --- a/mmv1/products/beyondcorp/product.yaml +++ b/mmv1/products/beyondcorp/product.yaml @@ -19,7 +19,3 @@ versions: base_url: https://beyondcorp.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Beyondcorp API - url: https://console.cloud.google.com/apis/library/beyondcorp.googleapis.com/ diff --git a/mmv1/products/biglake/product.yaml b/mmv1/products/biglake/product.yaml index 7d2070e9716f..93e6ec3f96a2 100644 --- a/mmv1/products/biglake/product.yaml +++ b/mmv1/products/biglake/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://biglake.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery -apis_required: - - !ruby/object:Api::Product::ApiReference - name: BigLake API - url: https://console.cloud.google.com/apis/library/biglake.googleapis.com/ diff --git a/mmv1/products/bigquery/product.yaml b/mmv1/products/bigquery/product.yaml index 8737e1242961..4738d4232d24 100644 --- a/mmv1/products/bigquery/product.yaml +++ b/mmv1/products/bigquery/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://bigquery.googleapis.com/bigquery/v2/ scopes: - https://www.googleapis.com/auth/bigquery -apis_required: - - !ruby/object:Api::Product::ApiReference - name: BigQuery API - url: https://console.cloud.google.com/apis/library/bigquery.googleapis.com/ diff --git a/mmv1/products/bigqueryanalyticshub/product.yaml b/mmv1/products/bigqueryanalyticshub/product.yaml index 5af9688704da..adefa3b29446 100644 --- a/mmv1/products/bigqueryanalyticshub/product.yaml +++ b/mmv1/products/bigqueryanalyticshub/product.yaml @@ -23,7 +23,3 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://analyticshub.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Bigquery Analytics Hub API - url: https://console.cloud.google.com/apis/library/analyticshub.googleapis.com/ diff --git a/mmv1/products/bigqueryconnection/product.yaml b/mmv1/products/bigqueryconnection/product.yaml index 3c20014a43c0..cad9df871600 100644 --- a/mmv1/products/bigqueryconnection/product.yaml +++ b/mmv1/products/bigqueryconnection/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://bigqueryconnection.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery -apis_required: - - !ruby/object:Api::Product::ApiReference - name: BigQueryConnection API - url: https://console.cloud.google.com/apis/api/bigqueryconnection.googleapis.com/ diff --git a/mmv1/products/bigquerydatapolicy/product.yaml b/mmv1/products/bigquerydatapolicy/product.yaml index 818b8604d18f..18dbd534c8e3 100644 --- a/mmv1/products/bigquerydatapolicy/product.yaml +++ b/mmv1/products/bigquerydatapolicy/product.yaml @@ -23,7 +23,3 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://bigquerydatapolicy.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: BigQuery Data Policy API - url: https://console.cloud.google.com/apis/library/bigquerydatapolicy.googleapis.com/ diff --git a/mmv1/products/bigquerydatatransfer/product.yaml b/mmv1/products/bigquerydatatransfer/product.yaml index a52590d74692..16ee455ab5f1 100644 --- a/mmv1/products/bigquerydatatransfer/product.yaml +++ b/mmv1/products/bigquerydatatransfer/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://bigquerydatatransfer.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery -apis_required: - - !ruby/object:Api::Product::ApiReference - name: BigQueryDataTransfer API - url: https://console.cloud.google.com/apis/api/bigquerydatatransfer.googleapis.com/ diff --git a/mmv1/products/bigqueryreservation/product.yaml b/mmv1/products/bigqueryreservation/product.yaml index 8449c84fb841..1361f10043c9 100644 --- a/mmv1/products/bigqueryreservation/product.yaml +++ b/mmv1/products/bigqueryreservation/product.yaml @@ -24,7 +24,3 @@ versions: base_url: https://bigqueryreservation.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery -apis_required: - - !ruby/object:Api::Product::ApiReference - name: BigQueryReservation API - url: https://console.cloud.google.com/apis/api/bigqueryreservation.googleapis.com/ diff --git a/mmv1/products/bigtable/product.yaml b/mmv1/products/bigtable/product.yaml index e41aa47579a0..68ad240371df 100644 --- a/mmv1/products/bigtable/product.yaml +++ b/mmv1/products/bigtable/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://bigtableadmin.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/bigtable -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Bigtable API - url: https://console.cloud.google.com/apis/library/bigtable.googleapis.com/ diff --git a/mmv1/products/billing/product.yaml b/mmv1/products/billing/product.yaml index 6b0711b6282c..926d88d2c360 100644 --- a/mmv1/products/billing/product.yaml +++ b/mmv1/products/billing/product.yaml @@ -24,7 +24,3 @@ versions: base_url: https://cloudbilling.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Billing - url: https://console.cloud.google.com/apis/library/cloudbilling.googleapis.com/ diff --git a/mmv1/products/billingbudget/product.yaml b/mmv1/products/billingbudget/product.yaml index 2363868c22ef..327c5b10e622 100644 --- a/mmv1/products/billingbudget/product.yaml +++ b/mmv1/products/billingbudget/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://billingbudgets.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Billing Budget - url: https://console.cloud.google.com/apis/library/billingbudgets.googleapis.com/ diff --git a/mmv1/products/certificatemanager/product.yaml b/mmv1/products/certificatemanager/product.yaml index 5753577bcc35..f147b0e1a1a7 100644 --- a/mmv1/products/certificatemanager/product.yaml +++ b/mmv1/products/certificatemanager/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://certificatemanager.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Network Services API - url: https://console.cloud.google.com/apis/library/certificatemanager.googleapis.com diff --git a/mmv1/products/cloudasset/product.yaml b/mmv1/products/cloudasset/product.yaml index 75ac4015241d..02ac179c5306 100644 --- a/mmv1/products/cloudasset/product.yaml +++ b/mmv1/products/cloudasset/product.yaml @@ -19,7 +19,3 @@ versions: base_url: https://cloudasset.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Asset API - url: https://console.cloud.google.com/apis/library/cloudasset.googleapis.com/ diff --git a/mmv1/products/cloudbuild/product.yaml b/mmv1/products/cloudbuild/product.yaml index b7d86da1f056..fb8740f5d960 100644 --- a/mmv1/products/cloudbuild/product.yaml +++ b/mmv1/products/cloudbuild/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://cloudbuild.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Build API - url: https://console.cloud.google.com/apis/library/cloudbuild.googleapis.com/ diff --git a/mmv1/products/cloudbuildv2/product.yaml b/mmv1/products/cloudbuildv2/product.yaml index 863190a0f4b7..d0d9616ec001 100644 --- a/mmv1/products/cloudbuildv2/product.yaml +++ b/mmv1/products/cloudbuildv2/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://cloudbuild.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Build API - url: https://console.cloud.google.com/apis/library/cloudbuild.googleapis.com/ diff --git a/mmv1/products/cloudfunctions/product.yaml b/mmv1/products/cloudfunctions/product.yaml index de4fa4922111..4f796f0f2867 100644 --- a/mmv1/products/cloudfunctions/product.yaml +++ b/mmv1/products/cloudfunctions/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://cloudfunctions.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Functions API - url: https://console.cloud.google.com/apis/library/cloudfunctions.googleapis.com/ diff --git a/mmv1/products/cloudfunctions2/product.yaml b/mmv1/products/cloudfunctions2/product.yaml index 29ca314a1513..09fbf22fa7dc 100644 --- a/mmv1/products/cloudfunctions2/product.yaml +++ b/mmv1/products/cloudfunctions2/product.yaml @@ -23,7 +23,3 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://cloudfunctions.googleapis.com/v2/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Functions API - url: https://console.cloud.google.com/apis/library/cloudfunctions.googleapis.com/ diff --git a/mmv1/products/cloudidentity/product.yaml b/mmv1/products/cloudidentity/product.yaml index 3821d8bd6555..47233708b0a0 100644 --- a/mmv1/products/cloudidentity/product.yaml +++ b/mmv1/products/cloudidentity/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://cloudidentity.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-identity -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Identity API - url: https://console.cloud.google.com/apis/api/cloudidentity.googleapis.com/overview diff --git a/mmv1/products/cloudids/product.yaml b/mmv1/products/cloudids/product.yaml index e9ce6f1d1451..36f529f6ed64 100644 --- a/mmv1/products/cloudids/product.yaml +++ b/mmv1/products/cloudids/product.yaml @@ -20,10 +20,6 @@ versions: base_url: https://ids.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloudids -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Intrusion Detection Service (IDS) API - url: https://console.cloud.google.com/apis/library/ids.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/cloudrunv2/product.yaml b/mmv1/products/cloudrunv2/product.yaml index ac223d16fc08..62b66cb326c8 100644 --- a/mmv1/products/cloudrunv2/product.yaml +++ b/mmv1/products/cloudrunv2/product.yaml @@ -23,7 +23,3 @@ versions: - !ruby/object:Api::Product::Version name: beta base_url: https://run.googleapis.com/v2/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Run API - url: https://console.cloud.google.com/apis/library/run.googleapis.com/ diff --git a/mmv1/products/cloudscheduler/product.yaml b/mmv1/products/cloudscheduler/product.yaml index 9c0b2bde6fa0..66e60b0e5433 100644 --- a/mmv1/products/cloudscheduler/product.yaml +++ b/mmv1/products/cloudscheduler/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://cloudscheduler.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Scheduler - url: https://console.cloud.google.com/apis/library/cloudscheduler.googleapis.com/ diff --git a/mmv1/products/cloudtasks/product.yaml b/mmv1/products/cloudtasks/product.yaml index 3530c72845d3..bd5687ce1488 100644 --- a/mmv1/products/cloudtasks/product.yaml +++ b/mmv1/products/cloudtasks/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://cloudtasks.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Tasks - url: https://console.cloud.google.com/apis/library/cloudtasks.googleapis.com/ diff --git a/mmv1/products/compute/product.yaml b/mmv1/products/compute/product.yaml index 8d9fd06ef595..1cd722004bf4 100644 --- a/mmv1/products/compute/product.yaml +++ b/mmv1/products/compute/product.yaml @@ -25,7 +25,3 @@ versions: base_url: https://compute.googleapis.com/compute/beta/ scopes: - https://www.googleapis.com/auth/compute -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Compute Engine API - url: https://console.cloud.google.com/apis/library/compute.googleapis.com/ diff --git a/mmv1/products/databasemigrationservice/product.yaml b/mmv1/products/databasemigrationservice/product.yaml index dd57cfde660f..0024866ca6e8 100644 --- a/mmv1/products/databasemigrationservice/product.yaml +++ b/mmv1/products/databasemigrationservice/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://datamigration.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Database Migration API - url: https://console.cloud.google.com/apis/library/datamigration.googleapis.com diff --git a/mmv1/products/datacatalog/product.yaml b/mmv1/products/datacatalog/product.yaml index a44cfe0acb6f..44b331563d2c 100644 --- a/mmv1/products/datacatalog/product.yaml +++ b/mmv1/products/datacatalog/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://datacatalog.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Google Cloud Data Catalog API - url: https://console.cloud.google.com/apis/library/datacatalog.googleapis.com diff --git a/mmv1/products/datafusion/product.yaml b/mmv1/products/datafusion/product.yaml index 1e7458d4a96d..b358c9be12ae 100644 --- a/mmv1/products/datafusion/product.yaml +++ b/mmv1/products/datafusion/product.yaml @@ -40,7 +40,3 @@ async: !ruby/object:Api::OpAsync error: !ruby/object:Api::OpAsync::Error path: 'error' message: 'message' -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Data Fusion API - url: https://console.cloud.google.com/apis/library/datafusion.googleapis.com diff --git a/mmv1/products/dataplex/product.yaml b/mmv1/products/dataplex/product.yaml index 7e6dea430ca9..7b4434bbf8ec 100644 --- a/mmv1/products/dataplex/product.yaml +++ b/mmv1/products/dataplex/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://dataplex.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Dataplex API - url: https://console.cloud.google.com/apis/library/dataplex.googleapis.com diff --git a/mmv1/products/dataproc/product.yaml b/mmv1/products/dataproc/product.yaml index ffe1034b0291..acf70992e563 100644 --- a/mmv1/products/dataproc/product.yaml +++ b/mmv1/products/dataproc/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://dataproc.googleapis.com/v1beta2/ scopes: - https://www.googleapis.com/auth/cloud-identity -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Dataproc API - url: https://console.cloud.google.com/apis/library/dataproc.googleapis.com diff --git a/mmv1/products/datastore/product.yaml b/mmv1/products/datastore/product.yaml index 837d2a1a840f..9326be25fa83 100644 --- a/mmv1/products/datastore/product.yaml +++ b/mmv1/products/datastore/product.yaml @@ -19,10 +19,6 @@ versions: base_url: https://datastore.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/datastore -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Datastore API - url: https://console.cloud.google.com/apis/library/datastore.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/datastream/product.yaml b/mmv1/products/datastream/product.yaml index d5a3f720158d..db9e4a5a5af5 100644 --- a/mmv1/products/datastream/product.yaml +++ b/mmv1/products/datastream/product.yaml @@ -19,10 +19,6 @@ versions: base_url: https://datastream.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Datastream API - url: https://console.cloud.google.com/apis/library/datastream.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/deploymentmanager/product.yaml b/mmv1/products/deploymentmanager/product.yaml index 3fe1235ed41f..119dd6f312f2 100644 --- a/mmv1/products/deploymentmanager/product.yaml +++ b/mmv1/products/deploymentmanager/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://www.googleapis.com/deploymentmanager/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Deployment Manager API - url: https://console.cloud.google.com/apis/library/deploymentmanager.googleapis.com/ diff --git a/mmv1/products/dialogflow/product.yaml b/mmv1/products/dialogflow/product.yaml index 234d46d7597e..b071ad685efd 100644 --- a/mmv1/products/dialogflow/product.yaml +++ b/mmv1/products/dialogflow/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://dialogflow.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Dialogflow API - url: https://console.cloud.google.com/apis/library/dialogflow.googleapis.com diff --git a/mmv1/products/dialogflowcx/product.yaml b/mmv1/products/dialogflowcx/product.yaml index 620bc0c296c9..67a46f177180 100644 --- a/mmv1/products/dialogflowcx/product.yaml +++ b/mmv1/products/dialogflowcx/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://{{location}}-dialogflow.googleapis.com/v3/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Dialogflow API - url: https://console.cloud.google.com/apis/library/dialogflow.googleapis.com diff --git a/mmv1/products/dns/product.yaml b/mmv1/products/dns/product.yaml index e52c4bd86d18..b2c51b1cdfa4 100644 --- a/mmv1/products/dns/product.yaml +++ b/mmv1/products/dns/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://dns.googleapis.com/dns/v1beta2/ scopes: - https://www.googleapis.com/auth/ndev.clouddns.readwrite -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Google Cloud DNS API - url: https://console.cloud.google.com/apis/library/dns.googleapis.com/ diff --git a/mmv1/products/documentai/product.yaml b/mmv1/products/documentai/product.yaml index c4de1f3c2903..27c16a6a1a8d 100644 --- a/mmv1/products/documentai/product.yaml +++ b/mmv1/products/documentai/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://{{location}}-documentai.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Document AI API - url: https://console.cloud.google.com/apis/api/documentai.googleapis.com/overview diff --git a/mmv1/products/documentaiwarehouse/product.yaml b/mmv1/products/documentaiwarehouse/product.yaml index 5493a6660cb2..cf1bca6a298c 100644 --- a/mmv1/products/documentaiwarehouse/product.yaml +++ b/mmv1/products/documentaiwarehouse/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://contentwarehouse.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Document AI Warehouse API - url: https://console.cloud.google.com/apis/library/contentwarehouse.googleapis.com/ diff --git a/mmv1/products/essentialcontacts/product.yaml b/mmv1/products/essentialcontacts/product.yaml index 9664e3fc0bec..b8b67e02b161 100644 --- a/mmv1/products/essentialcontacts/product.yaml +++ b/mmv1/products/essentialcontacts/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://essentialcontacts.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Essential Contacts API - url: https://console.cloud.google.com/apis/api/essentialcontacts.googleapis.com/overview diff --git a/mmv1/products/firebasedatabase/product.yaml b/mmv1/products/firebasedatabase/product.yaml index 3352fdee1b3f..29d4d27545c3 100644 --- a/mmv1/products/firebasedatabase/product.yaml +++ b/mmv1/products/firebasedatabase/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://firebasedatabase.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Firebase Realtime Database API - url: https://console.cloud.google.com/apis/library/firebasedatabase.googleapis.com/ diff --git a/mmv1/products/firebaseextensions/product.yaml b/mmv1/products/firebaseextensions/product.yaml index c63efe3bbf20..fc53a7e667dd 100644 --- a/mmv1/products/firebaseextensions/product.yaml +++ b/mmv1/products/firebaseextensions/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://firebaseextensions.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Firebase Extensions API - url: https://console.cloud.google.com/apis/library/firebaseextensions.googleapis.com/ diff --git a/mmv1/products/firestore/product.yaml b/mmv1/products/firestore/product.yaml index 1f5a68462689..ddf124162d59 100644 --- a/mmv1/products/firestore/product.yaml +++ b/mmv1/products/firestore/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://firestore.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Google Cloud Firestore API - url: https://console.cloud.google.com/apis/library/firestore.googleapis.com diff --git a/mmv1/products/gkebackup/product.yaml b/mmv1/products/gkebackup/product.yaml index 243ef5390b52..ba858ce19ed3 100644 --- a/mmv1/products/gkebackup/product.yaml +++ b/mmv1/products/gkebackup/product.yaml @@ -40,7 +40,3 @@ async: !ruby/object:Api::OpAsync error: !ruby/object:Api::OpAsync::Error path: 'error' message: 'message' -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Backup for GKE API - url: https://console.cloud.google.com/apis/library/gkebackup.googleapis.com diff --git a/mmv1/products/gkehub/product.yaml b/mmv1/products/gkehub/product.yaml index bc9bebbe7800..7de11c5f4842 100644 --- a/mmv1/products/gkehub/product.yaml +++ b/mmv1/products/gkehub/product.yaml @@ -24,7 +24,3 @@ versions: base_url: https://gkehub.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: GKEHub API - url: https://console.cloud.google.com/apis/library/gkehub.googleapis.com diff --git a/mmv1/products/gkehub2/product.yaml b/mmv1/products/gkehub2/product.yaml index 1cdc7430a937..649e6246c4a1 100644 --- a/mmv1/products/gkehub2/product.yaml +++ b/mmv1/products/gkehub2/product.yaml @@ -24,7 +24,3 @@ versions: base_url: https://gkehub.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: GKEHub API - url: https://console.cloud.google.com/apis/library/gkehub.googleapis.com diff --git a/mmv1/products/gkeonprem/product.yaml b/mmv1/products/gkeonprem/product.yaml index 6027ecb665ec..bd5b71a26eac 100644 --- a/mmv1/products/gkeonprem/product.yaml +++ b/mmv1/products/gkeonprem/product.yaml @@ -20,10 +20,6 @@ versions: base_url: https://gkeonprem.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Anthos On-Prem API - url: https://console.cloud.google.com/apis/library/gkeonprem.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation kind: 'gkeonprem#operation' diff --git a/mmv1/products/healthcare/product.yaml b/mmv1/products/healthcare/product.yaml index b75131d30f7d..98d508c164a6 100644 --- a/mmv1/products/healthcare/product.yaml +++ b/mmv1/products/healthcare/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://healthcare.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Healthcare API - url: https://console.cloud.google.com/apis/library/healthcare.googleapis.com/ diff --git a/mmv1/products/iam2/product.yaml b/mmv1/products/iam2/product.yaml index c856f35dea6d..7911ba2a12ab 100644 --- a/mmv1/products/iam2/product.yaml +++ b/mmv1/products/iam2/product.yaml @@ -24,10 +24,6 @@ versions: base_url: https://iam.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/iam -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Identity and Access Management (IAM) API - url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/iambeta/product.yaml b/mmv1/products/iambeta/product.yaml index 284843a60d2c..55786f97e1ec 100644 --- a/mmv1/products/iambeta/product.yaml +++ b/mmv1/products/iambeta/product.yaml @@ -24,10 +24,6 @@ versions: base_url: https://iam.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/iam -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Identity and Access Management (IAM) API - url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/iamworkforcepool/product.yaml b/mmv1/products/iamworkforcepool/product.yaml index 65b859518531..fb48c144d241 100644 --- a/mmv1/products/iamworkforcepool/product.yaml +++ b/mmv1/products/iamworkforcepool/product.yaml @@ -24,10 +24,6 @@ versions: base_url: https://iam.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/iam -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Identity and Access Management (IAM) API - url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/iap/product.yaml b/mmv1/products/iap/product.yaml index 851b68d1743c..6fbf8a2fbddc 100644 --- a/mmv1/products/iap/product.yaml +++ b/mmv1/products/iap/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://iap.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Identity-Aware Proxy - url: https://console.cloud.google.com/apis/library/iap.googleapis.com/ diff --git a/mmv1/products/identityplatform/product.yaml b/mmv1/products/identityplatform/product.yaml index c5ae1a8e323e..6a7766e64e11 100644 --- a/mmv1/products/identityplatform/product.yaml +++ b/mmv1/products/identityplatform/product.yaml @@ -22,7 +22,3 @@ scopes: - https://www.googleapis.com/auth/identitytoolkit - https://www.googleapis.com/auth/firebase - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Google Identity Platform - url: https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity/ diff --git a/mmv1/products/kms/product.yaml b/mmv1/products/kms/product.yaml index d49d04acc121..17295cea22e2 100644 --- a/mmv1/products/kms/product.yaml +++ b/mmv1/products/kms/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://cloudkms.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloudkms -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Key Management Service (KMS) API - url: https://console.cloud.google.com/apis/library/cloudkms.googleapis.com/ diff --git a/mmv1/products/logging/product.yaml b/mmv1/products/logging/product.yaml index 7e94a7db0860..e017f3f7f9e9 100644 --- a/mmv1/products/logging/product.yaml +++ b/mmv1/products/logging/product.yaml @@ -19,7 +19,3 @@ versions: base_url: https://logging.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Stackdriver Logging API - url: https://console.cloud.google.com/apis/library/logging.googleapis.com/ diff --git a/mmv1/products/looker/product.yaml b/mmv1/products/looker/product.yaml index 4d3d1aba79e1..39e6e9cd2e88 100644 --- a/mmv1/products/looker/product.yaml +++ b/mmv1/products/looker/product.yaml @@ -20,10 +20,6 @@ versions: base_url: https://looker.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Looker API - url: https://console.cloud.google.com/apis/library/looker.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/metastore/product.yaml b/mmv1/products/metastore/product.yaml index 8e3a29fdf9b9..83eb3d87cb9d 100644 --- a/mmv1/products/metastore/product.yaml +++ b/mmv1/products/metastore/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://metastore.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Dataproc Metastore API - url: https://console.cloud.google.com/apis/library/metastore.googleapis.com diff --git a/mmv1/products/mlengine/product.yaml b/mmv1/products/mlengine/product.yaml index a22ed3adcf55..88f09f7fe10c 100644 --- a/mmv1/products/mlengine/product.yaml +++ b/mmv1/products/mlengine/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://ml.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud ML - url: https://console.cloud.google.com/apis/library/ml.googleapis.com diff --git a/mmv1/products/monitoring/product.yaml b/mmv1/products/monitoring/product.yaml index deb7651d44fa..96e9992f5774 100644 --- a/mmv1/products/monitoring/product.yaml +++ b/mmv1/products/monitoring/product.yaml @@ -19,7 +19,3 @@ versions: base_url: https://monitoring.googleapis.com/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Stackdriver Monitoring API - url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com/ diff --git a/mmv1/products/networkconnectivity/product.yaml b/mmv1/products/networkconnectivity/product.yaml index 210044bd2cf8..6bea6bf40b70 100644 --- a/mmv1/products/networkconnectivity/product.yaml +++ b/mmv1/products/networkconnectivity/product.yaml @@ -20,8 +20,3 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://networkconnectivity.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Network Connectivity API - url: https://console.cloud.google.com/apis/library/networkconnectivity.googleapis.com/ - \ No newline at end of file diff --git a/mmv1/products/networkmanagement/product.yaml b/mmv1/products/networkmanagement/product.yaml index 90d8be0e69ba..63cc98193499 100644 --- a/mmv1/products/networkmanagement/product.yaml +++ b/mmv1/products/networkmanagement/product.yaml @@ -20,10 +20,6 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://networkmanagement.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Network Management API - url: https://console.cloud.google.com/apis/library/networkmanagement.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/networksecurity/product.yaml b/mmv1/products/networksecurity/product.yaml index 85ae621d8459..0d308e900f86 100644 --- a/mmv1/products/networksecurity/product.yaml +++ b/mmv1/products/networksecurity/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://networksecurity.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Network Security API - url: https://console.cloud.google.com/apis/library/networksecurity.googleapis.com diff --git a/mmv1/products/networkservices/product.yaml b/mmv1/products/networkservices/product.yaml index 38556fd15847..fc962b336f27 100644 --- a/mmv1/products/networkservices/product.yaml +++ b/mmv1/products/networkservices/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://networkservices.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Network Services API - url: https://console.cloud.google.com/apis/library/networkservices.googleapis.com diff --git a/mmv1/products/notebooks/product.yaml b/mmv1/products/notebooks/product.yaml index 179553c8f5a9..50d80716e490 100644 --- a/mmv1/products/notebooks/product.yaml +++ b/mmv1/products/notebooks/product.yaml @@ -27,10 +27,6 @@ versions: base_url: https://notebooks.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Notebooks API - url: https://console.cloud.google.com/apis/api/notebooks.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation base_url: '{{op_id}}' diff --git a/mmv1/products/orgpolicy/product.yaml b/mmv1/products/orgpolicy/product.yaml index 993a7c05c26d..c0f0540f562e 100644 --- a/mmv1/products/orgpolicy/product.yaml +++ b/mmv1/products/orgpolicy/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://orgpolicy.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Organization Policy API - url: https://console.cloud.google.com/apis/api/orgpolicy.googleapis.com/overview diff --git a/mmv1/products/osconfig/product.yaml b/mmv1/products/osconfig/product.yaml index e922b75bfacf..01d74be2526f 100644 --- a/mmv1/products/osconfig/product.yaml +++ b/mmv1/products/osconfig/product.yaml @@ -21,10 +21,6 @@ versions: - !ruby/object:Api::Product::Version name: beta base_url: https://osconfig.googleapis.com/v1beta/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Identity and Access Management (IAM) API - url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ scopes: - https://www.googleapis.com/auth/cloud-platform - https://www.googleapis.com/auth/compute diff --git a/mmv1/products/oslogin/product.yaml b/mmv1/products/oslogin/product.yaml index 8aedca5e8727..62498a0f9bd6 100644 --- a/mmv1/products/oslogin/product.yaml +++ b/mmv1/products/oslogin/product.yaml @@ -18,10 +18,6 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://oslogin.googleapis.com/v1/ -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Identity and Access Management (IAM) API - url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ scopes: - https://www.googleapis.com/auth/cloud-platform - https://www.googleapis.com/auth/compute diff --git a/mmv1/products/privateca/product.yaml b/mmv1/products/privateca/product.yaml index 11bf7804df5c..d310b6591787 100644 --- a/mmv1/products/privateca/product.yaml +++ b/mmv1/products/privateca/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://privateca.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Certificate Authority API - url: https://console.cloud.google.com/apis/api/privateca.googleapis.com diff --git a/mmv1/products/publicca/product.yaml b/mmv1/products/publicca/product.yaml index ea8152a52141..6243c8d6c677 100644 --- a/mmv1/products/publicca/product.yaml +++ b/mmv1/products/publicca/product.yaml @@ -22,7 +22,3 @@ versions: base_url: https://publicca.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Public Certificate Authority API - url: https://console.cloud.google.com/apis/library/publicca.googleapis.com diff --git a/mmv1/products/pubsub/product.yaml b/mmv1/products/pubsub/product.yaml index f63d92f5d171..fee2f465bb07 100644 --- a/mmv1/products/pubsub/product.yaml +++ b/mmv1/products/pubsub/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://pubsub.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/pubsub -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Pub/Sub API - url: https://console.cloud.google.com/apis/library/pubsub.googleapis.com/ diff --git a/mmv1/products/pubsublite/product.yaml b/mmv1/products/pubsublite/product.yaml index 236999876cb6..48e342b3ae62 100644 --- a/mmv1/products/pubsublite/product.yaml +++ b/mmv1/products/pubsublite/product.yaml @@ -21,7 +21,3 @@ versions: cai_base_url: https://pubsublite.googleapis.com/v1/admin/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Pub/Sub Lite API - url: https://console.cloud.google.com/apis/library/pubsublite.googleapis.com/ diff --git a/mmv1/products/resourcemanager/product.yaml b/mmv1/products/resourcemanager/product.yaml index 33569faf075f..f7ccd2fa3826 100644 --- a/mmv1/products/resourcemanager/product.yaml +++ b/mmv1/products/resourcemanager/product.yaml @@ -21,7 +21,3 @@ versions: scopes: # All access is needed to create projects. - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Resource Manager API - url: https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com/ diff --git a/mmv1/products/runtimeconfig/product.yaml b/mmv1/products/runtimeconfig/product.yaml index 9d7cbf6db3e5..0f5f582cdb8b 100644 --- a/mmv1/products/runtimeconfig/product.yaml +++ b/mmv1/products/runtimeconfig/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://runtimeconfig.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloudruntimeconfig -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Resource Manager API - url: https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com/ diff --git a/mmv1/products/secretmanager/product.yaml b/mmv1/products/secretmanager/product.yaml index a94a4f7e74cc..e08b510702c9 100644 --- a/mmv1/products/secretmanager/product.yaml +++ b/mmv1/products/secretmanager/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://secretmanager.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Secret Manager API - url: https://console.cloud.google.com/apis/library/secretmanager.googleapis.com/ diff --git a/mmv1/products/securityscanner/product.yaml b/mmv1/products/securityscanner/product.yaml index 928368b06b9f..20f8504a48c3 100644 --- a/mmv1/products/securityscanner/product.yaml +++ b/mmv1/products/securityscanner/product.yaml @@ -19,7 +19,3 @@ versions: base_url: https://websecurityscanner.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Web Security Scanner API - url: https://console.cloud.google.com/apis/library/websecurityscanner.googleapis.com/ diff --git a/mmv1/products/servicedirectory/product.yaml b/mmv1/products/servicedirectory/product.yaml index 2fc20e6f77fd..964241bcf264 100644 --- a/mmv1/products/servicedirectory/product.yaml +++ b/mmv1/products/servicedirectory/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://servicedirectory.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Service Directory API - url: https://console.cloud.google.com/apis/library/servicedirectory.googleapis.com/ diff --git a/mmv1/products/servicemanagement/product.yaml b/mmv1/products/servicemanagement/product.yaml index cb3cc794a3eb..6152d8382140 100644 --- a/mmv1/products/servicemanagement/product.yaml +++ b/mmv1/products/servicemanagement/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://servicemanagement.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloudplatform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Service Management API - url: https://console.cloud.google.com/apis/library/servicemanagement.googleapis.com/ diff --git a/mmv1/products/serviceusage/product.yaml b/mmv1/products/serviceusage/product.yaml index 36672796aab6..27e40852210e 100644 --- a/mmv1/products/serviceusage/product.yaml +++ b/mmv1/products/serviceusage/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://serviceusage.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Service Usage API - url: https://console.cloud.google.com/apis/library/serviceusage.googleapis.com/ diff --git a/mmv1/products/sourcerepo/product.yaml b/mmv1/products/sourcerepo/product.yaml index d4717e5d1258..e78f0569cd34 100644 --- a/mmv1/products/sourcerepo/product.yaml +++ b/mmv1/products/sourcerepo/product.yaml @@ -21,7 +21,3 @@ versions: base_url: https://sourcerepo.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Source Repositories API - url: https://console.cloud.google.com/apis/library/sourcerepo.googleapis.com/ diff --git a/mmv1/products/spanner/product.yaml b/mmv1/products/spanner/product.yaml index 87e0f1204e19..883226d15cd3 100644 --- a/mmv1/products/spanner/product.yaml +++ b/mmv1/products/spanner/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://spanner.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/spanner.admin -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Spanner API - url: https://console.cloud.google.com/apis/library/spanner.googleapis.com/ diff --git a/mmv1/products/sql/product.yaml b/mmv1/products/sql/product.yaml index 42fdd7a2100d..5658ae7e1975 100644 --- a/mmv1/products/sql/product.yaml +++ b/mmv1/products/sql/product.yaml @@ -21,10 +21,6 @@ versions: base_url: https://sqladmin.googleapis.com/sql/v1beta4/ scopes: - https://www.googleapis.com/auth/sqlservice.admin -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud SQL Admin API - url: https://console.cloud.google.com/apis/library/sqladmin.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation kind: 'sql#operation' diff --git a/mmv1/products/storage/product.yaml b/mmv1/products/storage/product.yaml index 4d380b12ef79..458a2e7f5e19 100644 --- a/mmv1/products/storage/product.yaml +++ b/mmv1/products/storage/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://storage.googleapis.com/storage/v1/ scopes: - https://www.googleapis.com/auth/devstorage.full_control -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Google Cloud Storage - url: https://console.cloud.google.com/apis/library/storage-component.googleapis.com/ diff --git a/mmv1/products/storageinsights/product.yaml b/mmv1/products/storageinsights/product.yaml index 7f7a0b22e93c..e43481d0e456 100644 --- a/mmv1/products/storageinsights/product.yaml +++ b/mmv1/products/storageinsights/product.yaml @@ -20,10 +20,3 @@ versions: base_url: https://storageinsights.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/devstorage.full_control -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Google Cloud Storage - url: https://console.cloud.google.com/apis/library/storage-component.googleapis.com/ - - !ruby/object:Api::Product::ApiReference - name: Google Cloud Storage Insights - url: https://console.cloud.google.com/apis/library/storageinsights.googleapis.com/ diff --git a/mmv1/products/storagetransfer/product.yaml b/mmv1/products/storagetransfer/product.yaml index 31709ea7c94c..62d3765c7a91 100644 --- a/mmv1/products/storagetransfer/product.yaml +++ b/mmv1/products/storagetransfer/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://storagetransfer.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Storage Transfer API - url: https://console.cloud.google.com/apis/library/storagetransfer.googleapis.com/ diff --git a/mmv1/products/vmwareengine/product.yaml b/mmv1/products/vmwareengine/product.yaml index 5d6e08562005..f55c85d8bced 100644 --- a/mmv1/products/vmwareengine/product.yaml +++ b/mmv1/products/vmwareengine/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://vmwareengine.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: VMwareEngine API - url: https://console.cloud.google.com/apis/library/vmwareengine.googleapis.com/ diff --git a/mmv1/products/vpcaccess/product.yaml b/mmv1/products/vpcaccess/product.yaml index 86e93dcd1a99..ff79d8e6791e 100644 --- a/mmv1/products/vpcaccess/product.yaml +++ b/mmv1/products/vpcaccess/product.yaml @@ -23,7 +23,3 @@ versions: base_url: https://vpcaccess.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Serverless VPC Access API - url: https://console.cloud.google.com/apis/library/vpcaccess.googleapis.com/ diff --git a/mmv1/products/workflows/product.yaml b/mmv1/products/workflows/product.yaml index 2f84e8ef20d4..f014e8edd8ae 100644 --- a/mmv1/products/workflows/product.yaml +++ b/mmv1/products/workflows/product.yaml @@ -23,10 +23,6 @@ versions: base_url: https://workflows.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Workflows API - url: https://console.cloud.google.com/apis/library/workflows.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/workstations/product.yaml b/mmv1/products/workstations/product.yaml index 751e8051212b..f219cbb130ad 100644 --- a/mmv1/products/workstations/product.yaml +++ b/mmv1/products/workstations/product.yaml @@ -20,7 +20,3 @@ versions: base_url: https://workstations.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform -apis_required: - - !ruby/object:Api::Product::ApiReference - name: Cloud Workstations API - url: https://console.cloud.google.com/apis/library/workstations.googleapis.com From 657f63cdcb856d50ca3614740c722258c2e37fc4 Mon Sep 17 00:00:00 2001 From: Scott Suarez Date: Thu, 14 Sep 2023 10:16:33 -0700 Subject: [PATCH 067/476] Update version_5_upgrade.html.markdown (#8933) --- .../docs/guides/version_5_upgrade.html.markdown | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown index 88ec1304641f..ea8677a03b5c 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown @@ -443,6 +443,17 @@ resource "google_project_iam_binding" "gcs-bucket-writer" { ] } ``` + +## Resource: `google_cloudfunctions2_function` +### `location` now a required field +Deployment would fail if this field was unspecified. Marked this field as requied to align with implementation. This value cannot be inferred from any provider level config. No change is necessary for upgrade as this field is already needed for any deployments. + +## Resource: `google_cloud_run_v2_service` +### transitioned `volumes.cloud_sql_instance.instances` to SET from ARRAY for `google_cloud_run_v2_service` +Previously, `database_flags` was a list, making it order-dependent. It is now a set. + +If you were relying on accessing an individual flag by index (for example, `google_sql_database_instance.instance.settings.0.database_flags.0.name`), then that will now need to by hash (for example, `google_sql_database_instance.instance.settings.0.database_flags..name`). + ## Product: `cloudiot` ### resource `google_cloudiot_device` is now removed From 225790a55e589feacdf2eceba03da28ad30b9508 Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Thu, 14 Sep 2023 12:34:03 -0500 Subject: [PATCH 068/476] Revert "Remove api_reference (apis_required) (#8947)" (#8956) --- mmv1/api/product.rb | 6 ++++ mmv1/api/product/api_reference.rb | 30 +++++++++++++++++++ mmv1/products/accessapproval/product.yaml | 4 +++ mmv1/products/alloydb/product.yaml | 4 +++ mmv1/products/apigee/product.yaml | 4 +++ mmv1/products/appengine/product.yaml | 4 +++ mmv1/products/artifactregistry/product.yaml | 4 +++ mmv1/products/backupdr/product.yaml | 4 +++ mmv1/products/beyondcorp/product.yaml | 4 +++ mmv1/products/biglake/product.yaml | 4 +++ mmv1/products/bigquery/product.yaml | 4 +++ .../bigqueryanalyticshub/product.yaml | 4 +++ mmv1/products/bigqueryconnection/product.yaml | 4 +++ mmv1/products/bigquerydatapolicy/product.yaml | 4 +++ .../bigquerydatatransfer/product.yaml | 4 +++ .../products/bigqueryreservation/product.yaml | 4 +++ mmv1/products/bigtable/product.yaml | 4 +++ mmv1/products/billing/product.yaml | 4 +++ mmv1/products/billingbudget/product.yaml | 4 +++ mmv1/products/certificatemanager/product.yaml | 4 +++ mmv1/products/cloudasset/product.yaml | 4 +++ mmv1/products/cloudbuild/product.yaml | 4 +++ mmv1/products/cloudbuildv2/product.yaml | 4 +++ mmv1/products/cloudfunctions/product.yaml | 4 +++ mmv1/products/cloudfunctions2/product.yaml | 4 +++ mmv1/products/cloudidentity/product.yaml | 4 +++ mmv1/products/cloudids/product.yaml | 4 +++ mmv1/products/cloudrunv2/product.yaml | 4 +++ mmv1/products/cloudscheduler/product.yaml | 4 +++ mmv1/products/cloudtasks/product.yaml | 4 +++ mmv1/products/compute/product.yaml | 4 +++ .../databasemigrationservice/product.yaml | 4 +++ mmv1/products/datacatalog/product.yaml | 4 +++ mmv1/products/datafusion/product.yaml | 4 +++ mmv1/products/dataplex/product.yaml | 4 +++ mmv1/products/dataproc/product.yaml | 4 +++ mmv1/products/datastore/product.yaml | 4 +++ mmv1/products/datastream/product.yaml | 4 +++ mmv1/products/deploymentmanager/product.yaml | 4 +++ mmv1/products/dialogflow/product.yaml | 4 +++ mmv1/products/dialogflowcx/product.yaml | 4 +++ mmv1/products/dns/product.yaml | 4 +++ mmv1/products/documentai/product.yaml | 4 +++ .../products/documentaiwarehouse/product.yaml | 4 +++ mmv1/products/essentialcontacts/product.yaml | 4 +++ mmv1/products/firebasedatabase/product.yaml | 4 +++ mmv1/products/firebaseextensions/product.yaml | 4 +++ mmv1/products/firestore/product.yaml | 4 +++ mmv1/products/gkebackup/product.yaml | 4 +++ mmv1/products/gkehub/product.yaml | 4 +++ mmv1/products/gkehub2/product.yaml | 4 +++ mmv1/products/gkeonprem/product.yaml | 4 +++ mmv1/products/healthcare/product.yaml | 4 +++ mmv1/products/iam2/product.yaml | 4 +++ mmv1/products/iambeta/product.yaml | 4 +++ mmv1/products/iamworkforcepool/product.yaml | 4 +++ mmv1/products/iap/product.yaml | 4 +++ mmv1/products/identityplatform/product.yaml | 4 +++ mmv1/products/kms/product.yaml | 4 +++ mmv1/products/logging/product.yaml | 4 +++ mmv1/products/looker/product.yaml | 4 +++ mmv1/products/metastore/product.yaml | 4 +++ mmv1/products/mlengine/product.yaml | 4 +++ mmv1/products/monitoring/product.yaml | 4 +++ .../products/networkconnectivity/product.yaml | 4 +++ mmv1/products/networkmanagement/product.yaml | 4 +++ mmv1/products/networksecurity/product.yaml | 4 +++ mmv1/products/networkservices/product.yaml | 4 +++ mmv1/products/notebooks/product.yaml | 4 +++ mmv1/products/orgpolicy/product.yaml | 4 +++ mmv1/products/osconfig/product.yaml | 4 +++ mmv1/products/oslogin/product.yaml | 4 +++ mmv1/products/privateca/product.yaml | 4 +++ mmv1/products/publicca/product.yaml | 4 +++ mmv1/products/pubsub/product.yaml | 4 +++ mmv1/products/pubsublite/product.yaml | 4 +++ mmv1/products/resourcemanager/product.yaml | 4 +++ mmv1/products/runtimeconfig/product.yaml | 4 +++ mmv1/products/secretmanager/product.yaml | 4 +++ mmv1/products/securityscanner/product.yaml | 4 +++ mmv1/products/servicedirectory/product.yaml | 4 +++ mmv1/products/servicemanagement/product.yaml | 4 +++ mmv1/products/serviceusage/product.yaml | 4 +++ mmv1/products/sourcerepo/product.yaml | 4 +++ mmv1/products/spanner/product.yaml | 4 +++ mmv1/products/sql/product.yaml | 4 +++ mmv1/products/storage/product.yaml | 4 +++ mmv1/products/storageinsights/product.yaml | 7 +++++ mmv1/products/storagetransfer/product.yaml | 4 +++ mmv1/products/vmwareengine/product.yaml | 4 +++ mmv1/products/vpcaccess/product.yaml | 4 +++ mmv1/products/workflows/product.yaml | 4 +++ mmv1/products/workstations/product.yaml | 4 +++ 93 files changed, 403 insertions(+) create mode 100644 mmv1/api/product/api_reference.rb diff --git a/mmv1/api/product.rb b/mmv1/api/product.rb index e5964f986348..2faca615f254 100644 --- a/mmv1/api/product.rb +++ b/mmv1/api/product.rb @@ -12,6 +12,7 @@ # limitations under the License. require 'api/object' +require 'api/product/api_reference' require 'api/product/version' require 'google/logger' require 'compile/core' @@ -51,6 +52,10 @@ class Product < Api::Object::Named # failures on operation_get. see github.com/hashicorp/terraform-provider-google/issues/9489 attr_reader :operation_retry + # The APIs required to be enabled for this product. + # Usually just the product's API + attr_reader :apis_required + attr_reader :async attr_reader :legacy_name @@ -70,6 +75,7 @@ def validate check :display_name, type: String check :objects, type: Array, item_type: Api::Resource check :scopes, type: Array, item_type: String, required: true + check :apis_required, type: Array, item_type: Api::Product::ApiReference check :operation_retry, type: String check :async, type: Api::Async diff --git a/mmv1/api/product/api_reference.rb b/mmv1/api/product/api_reference.rb new file mode 100644 index 000000000000..aae8278f2438 --- /dev/null +++ b/mmv1/api/product/api_reference.rb @@ -0,0 +1,30 @@ +# Copyright 2019 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. + +require 'api/object' + +module Api + class Product < Api::Object::Named + # Represents any APIs that are required to be enabled to use this product + class ApiReference < Api::Object + attr_reader :name + attr_reader :url + + def validate + super + check :name, type: String, required: true + check :url, type: String, required: true + end + end + end +end diff --git a/mmv1/products/accessapproval/product.yaml b/mmv1/products/accessapproval/product.yaml index ec7d98243638..70df0a4a85f0 100644 --- a/mmv1/products/accessapproval/product.yaml +++ b/mmv1/products/accessapproval/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://accessapproval.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Access Approval + url: https://console.cloud.google.com/apis/library/accessapproval.googleapis.com/ diff --git a/mmv1/products/alloydb/product.yaml b/mmv1/products/alloydb/product.yaml index b9f45eba5d98..dd03681b3583 100644 --- a/mmv1/products/alloydb/product.yaml +++ b/mmv1/products/alloydb/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://alloydb.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity +apis_required: + - !ruby/object:Api::Product::ApiReference + name: AlloyDB API + url: https://console.cloud.google.com/apis/library/alloydb.googleapis.com diff --git a/mmv1/products/apigee/product.yaml b/mmv1/products/apigee/product.yaml index 4f6c7104702f..b5187a753967 100644 --- a/mmv1/products/apigee/product.yaml +++ b/mmv1/products/apigee/product.yaml @@ -27,3 +27,7 @@ versions: base_url: https://apigee.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Apigee API + url: https://console.cloud.google.com/apis/library/apigee.googleapis.com/ diff --git a/mmv1/products/appengine/product.yaml b/mmv1/products/appengine/product.yaml index 4c091be92ae5..699ca84efae5 100644 --- a/mmv1/products/appengine/product.yaml +++ b/mmv1/products/appengine/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://appengine.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: App Engine Admin API + url: https://console.cloud.google.com/apis/library/appengine.googleapis.com/ diff --git a/mmv1/products/artifactregistry/product.yaml b/mmv1/products/artifactregistry/product.yaml index 068579383829..e7eb589a7f91 100644 --- a/mmv1/products/artifactregistry/product.yaml +++ b/mmv1/products/artifactregistry/product.yaml @@ -23,6 +23,10 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://artifactregistry.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Artifact Registry API + url: https://console.cloud.google.com/apis/library/artifactregistry.googleapis.com/ async: !ruby/object:Api::OpAsync actions: ['create', 'delete'] operation: !ruby/object:Api::OpAsync::Operation diff --git a/mmv1/products/backupdr/product.yaml b/mmv1/products/backupdr/product.yaml index 2156cac27c3b..43ddaff88eb9 100644 --- a/mmv1/products/backupdr/product.yaml +++ b/mmv1/products/backupdr/product.yaml @@ -20,6 +20,10 @@ versions: - !ruby/object:Api::Product::Version name: beta base_url: https://backupdr.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Backup and DR API + url: https://console.cloud.google.com/apis/library/backupdr.googleapis.com/ async: !ruby/object:Api::OpAsync actions: ['create', 'delete'] operation: !ruby/object:Api::OpAsync::Operation diff --git a/mmv1/products/beyondcorp/product.yaml b/mmv1/products/beyondcorp/product.yaml index 39be52f97c04..eea11e715b7c 100644 --- a/mmv1/products/beyondcorp/product.yaml +++ b/mmv1/products/beyondcorp/product.yaml @@ -19,3 +19,7 @@ versions: base_url: https://beyondcorp.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Beyondcorp API + url: https://console.cloud.google.com/apis/library/beyondcorp.googleapis.com/ diff --git a/mmv1/products/biglake/product.yaml b/mmv1/products/biglake/product.yaml index 93e6ec3f96a2..7d2070e9716f 100644 --- a/mmv1/products/biglake/product.yaml +++ b/mmv1/products/biglake/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://biglake.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery +apis_required: + - !ruby/object:Api::Product::ApiReference + name: BigLake API + url: https://console.cloud.google.com/apis/library/biglake.googleapis.com/ diff --git a/mmv1/products/bigquery/product.yaml b/mmv1/products/bigquery/product.yaml index 4738d4232d24..8737e1242961 100644 --- a/mmv1/products/bigquery/product.yaml +++ b/mmv1/products/bigquery/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://bigquery.googleapis.com/bigquery/v2/ scopes: - https://www.googleapis.com/auth/bigquery +apis_required: + - !ruby/object:Api::Product::ApiReference + name: BigQuery API + url: https://console.cloud.google.com/apis/library/bigquery.googleapis.com/ diff --git a/mmv1/products/bigqueryanalyticshub/product.yaml b/mmv1/products/bigqueryanalyticshub/product.yaml index adefa3b29446..5af9688704da 100644 --- a/mmv1/products/bigqueryanalyticshub/product.yaml +++ b/mmv1/products/bigqueryanalyticshub/product.yaml @@ -23,3 +23,7 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://analyticshub.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Bigquery Analytics Hub API + url: https://console.cloud.google.com/apis/library/analyticshub.googleapis.com/ diff --git a/mmv1/products/bigqueryconnection/product.yaml b/mmv1/products/bigqueryconnection/product.yaml index cad9df871600..3c20014a43c0 100644 --- a/mmv1/products/bigqueryconnection/product.yaml +++ b/mmv1/products/bigqueryconnection/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://bigqueryconnection.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery +apis_required: + - !ruby/object:Api::Product::ApiReference + name: BigQueryConnection API + url: https://console.cloud.google.com/apis/api/bigqueryconnection.googleapis.com/ diff --git a/mmv1/products/bigquerydatapolicy/product.yaml b/mmv1/products/bigquerydatapolicy/product.yaml index 18dbd534c8e3..818b8604d18f 100644 --- a/mmv1/products/bigquerydatapolicy/product.yaml +++ b/mmv1/products/bigquerydatapolicy/product.yaml @@ -23,3 +23,7 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://bigquerydatapolicy.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: BigQuery Data Policy API + url: https://console.cloud.google.com/apis/library/bigquerydatapolicy.googleapis.com/ diff --git a/mmv1/products/bigquerydatatransfer/product.yaml b/mmv1/products/bigquerydatatransfer/product.yaml index 16ee455ab5f1..a52590d74692 100644 --- a/mmv1/products/bigquerydatatransfer/product.yaml +++ b/mmv1/products/bigquerydatatransfer/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://bigquerydatatransfer.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery +apis_required: + - !ruby/object:Api::Product::ApiReference + name: BigQueryDataTransfer API + url: https://console.cloud.google.com/apis/api/bigquerydatatransfer.googleapis.com/ diff --git a/mmv1/products/bigqueryreservation/product.yaml b/mmv1/products/bigqueryreservation/product.yaml index 1361f10043c9..8449c84fb841 100644 --- a/mmv1/products/bigqueryreservation/product.yaml +++ b/mmv1/products/bigqueryreservation/product.yaml @@ -24,3 +24,7 @@ versions: base_url: https://bigqueryreservation.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/bigquery +apis_required: + - !ruby/object:Api::Product::ApiReference + name: BigQueryReservation API + url: https://console.cloud.google.com/apis/api/bigqueryreservation.googleapis.com/ diff --git a/mmv1/products/bigtable/product.yaml b/mmv1/products/bigtable/product.yaml index 68ad240371df..e41aa47579a0 100644 --- a/mmv1/products/bigtable/product.yaml +++ b/mmv1/products/bigtable/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://bigtableadmin.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/bigtable +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Bigtable API + url: https://console.cloud.google.com/apis/library/bigtable.googleapis.com/ diff --git a/mmv1/products/billing/product.yaml b/mmv1/products/billing/product.yaml index 926d88d2c360..6b0711b6282c 100644 --- a/mmv1/products/billing/product.yaml +++ b/mmv1/products/billing/product.yaml @@ -24,3 +24,7 @@ versions: base_url: https://cloudbilling.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Billing + url: https://console.cloud.google.com/apis/library/cloudbilling.googleapis.com/ diff --git a/mmv1/products/billingbudget/product.yaml b/mmv1/products/billingbudget/product.yaml index 327c5b10e622..2363868c22ef 100644 --- a/mmv1/products/billingbudget/product.yaml +++ b/mmv1/products/billingbudget/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://billingbudgets.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Billing Budget + url: https://console.cloud.google.com/apis/library/billingbudgets.googleapis.com/ diff --git a/mmv1/products/certificatemanager/product.yaml b/mmv1/products/certificatemanager/product.yaml index f147b0e1a1a7..5753577bcc35 100644 --- a/mmv1/products/certificatemanager/product.yaml +++ b/mmv1/products/certificatemanager/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://certificatemanager.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Network Services API + url: https://console.cloud.google.com/apis/library/certificatemanager.googleapis.com diff --git a/mmv1/products/cloudasset/product.yaml b/mmv1/products/cloudasset/product.yaml index 02ac179c5306..75ac4015241d 100644 --- a/mmv1/products/cloudasset/product.yaml +++ b/mmv1/products/cloudasset/product.yaml @@ -19,3 +19,7 @@ versions: base_url: https://cloudasset.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Asset API + url: https://console.cloud.google.com/apis/library/cloudasset.googleapis.com/ diff --git a/mmv1/products/cloudbuild/product.yaml b/mmv1/products/cloudbuild/product.yaml index fb8740f5d960..b7d86da1f056 100644 --- a/mmv1/products/cloudbuild/product.yaml +++ b/mmv1/products/cloudbuild/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://cloudbuild.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Build API + url: https://console.cloud.google.com/apis/library/cloudbuild.googleapis.com/ diff --git a/mmv1/products/cloudbuildv2/product.yaml b/mmv1/products/cloudbuildv2/product.yaml index d0d9616ec001..863190a0f4b7 100644 --- a/mmv1/products/cloudbuildv2/product.yaml +++ b/mmv1/products/cloudbuildv2/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://cloudbuild.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Build API + url: https://console.cloud.google.com/apis/library/cloudbuild.googleapis.com/ diff --git a/mmv1/products/cloudfunctions/product.yaml b/mmv1/products/cloudfunctions/product.yaml index 4f796f0f2867..de4fa4922111 100644 --- a/mmv1/products/cloudfunctions/product.yaml +++ b/mmv1/products/cloudfunctions/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://cloudfunctions.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Functions API + url: https://console.cloud.google.com/apis/library/cloudfunctions.googleapis.com/ diff --git a/mmv1/products/cloudfunctions2/product.yaml b/mmv1/products/cloudfunctions2/product.yaml index 09fbf22fa7dc..29ca314a1513 100644 --- a/mmv1/products/cloudfunctions2/product.yaml +++ b/mmv1/products/cloudfunctions2/product.yaml @@ -23,3 +23,7 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://cloudfunctions.googleapis.com/v2/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Functions API + url: https://console.cloud.google.com/apis/library/cloudfunctions.googleapis.com/ diff --git a/mmv1/products/cloudidentity/product.yaml b/mmv1/products/cloudidentity/product.yaml index 47233708b0a0..3821d8bd6555 100644 --- a/mmv1/products/cloudidentity/product.yaml +++ b/mmv1/products/cloudidentity/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://cloudidentity.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-identity +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Identity API + url: https://console.cloud.google.com/apis/api/cloudidentity.googleapis.com/overview diff --git a/mmv1/products/cloudids/product.yaml b/mmv1/products/cloudids/product.yaml index 36f529f6ed64..e9ce6f1d1451 100644 --- a/mmv1/products/cloudids/product.yaml +++ b/mmv1/products/cloudids/product.yaml @@ -20,6 +20,10 @@ versions: base_url: https://ids.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloudids +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Intrusion Detection Service (IDS) API + url: https://console.cloud.google.com/apis/library/ids.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/cloudrunv2/product.yaml b/mmv1/products/cloudrunv2/product.yaml index 62b66cb326c8..ac223d16fc08 100644 --- a/mmv1/products/cloudrunv2/product.yaml +++ b/mmv1/products/cloudrunv2/product.yaml @@ -23,3 +23,7 @@ versions: - !ruby/object:Api::Product::Version name: beta base_url: https://run.googleapis.com/v2/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Run API + url: https://console.cloud.google.com/apis/library/run.googleapis.com/ diff --git a/mmv1/products/cloudscheduler/product.yaml b/mmv1/products/cloudscheduler/product.yaml index 66e60b0e5433..9c0b2bde6fa0 100644 --- a/mmv1/products/cloudscheduler/product.yaml +++ b/mmv1/products/cloudscheduler/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://cloudscheduler.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Scheduler + url: https://console.cloud.google.com/apis/library/cloudscheduler.googleapis.com/ diff --git a/mmv1/products/cloudtasks/product.yaml b/mmv1/products/cloudtasks/product.yaml index bd5687ce1488..3530c72845d3 100644 --- a/mmv1/products/cloudtasks/product.yaml +++ b/mmv1/products/cloudtasks/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://cloudtasks.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Tasks + url: https://console.cloud.google.com/apis/library/cloudtasks.googleapis.com/ diff --git a/mmv1/products/compute/product.yaml b/mmv1/products/compute/product.yaml index 1cd722004bf4..8d9fd06ef595 100644 --- a/mmv1/products/compute/product.yaml +++ b/mmv1/products/compute/product.yaml @@ -25,3 +25,7 @@ versions: base_url: https://compute.googleapis.com/compute/beta/ scopes: - https://www.googleapis.com/auth/compute +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Compute Engine API + url: https://console.cloud.google.com/apis/library/compute.googleapis.com/ diff --git a/mmv1/products/databasemigrationservice/product.yaml b/mmv1/products/databasemigrationservice/product.yaml index 0024866ca6e8..dd57cfde660f 100644 --- a/mmv1/products/databasemigrationservice/product.yaml +++ b/mmv1/products/databasemigrationservice/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://datamigration.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Database Migration API + url: https://console.cloud.google.com/apis/library/datamigration.googleapis.com diff --git a/mmv1/products/datacatalog/product.yaml b/mmv1/products/datacatalog/product.yaml index 44b331563d2c..a44cfe0acb6f 100644 --- a/mmv1/products/datacatalog/product.yaml +++ b/mmv1/products/datacatalog/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://datacatalog.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Data Catalog API + url: https://console.cloud.google.com/apis/library/datacatalog.googleapis.com diff --git a/mmv1/products/datafusion/product.yaml b/mmv1/products/datafusion/product.yaml index b358c9be12ae..1e7458d4a96d 100644 --- a/mmv1/products/datafusion/product.yaml +++ b/mmv1/products/datafusion/product.yaml @@ -40,3 +40,7 @@ async: !ruby/object:Api::OpAsync error: !ruby/object:Api::OpAsync::Error path: 'error' message: 'message' +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Data Fusion API + url: https://console.cloud.google.com/apis/library/datafusion.googleapis.com diff --git a/mmv1/products/dataplex/product.yaml b/mmv1/products/dataplex/product.yaml index 7b4434bbf8ec..7e6dea430ca9 100644 --- a/mmv1/products/dataplex/product.yaml +++ b/mmv1/products/dataplex/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://dataplex.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Dataplex API + url: https://console.cloud.google.com/apis/library/dataplex.googleapis.com diff --git a/mmv1/products/dataproc/product.yaml b/mmv1/products/dataproc/product.yaml index acf70992e563..ffe1034b0291 100644 --- a/mmv1/products/dataproc/product.yaml +++ b/mmv1/products/dataproc/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://dataproc.googleapis.com/v1beta2/ scopes: - https://www.googleapis.com/auth/cloud-identity +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Dataproc API + url: https://console.cloud.google.com/apis/library/dataproc.googleapis.com diff --git a/mmv1/products/datastore/product.yaml b/mmv1/products/datastore/product.yaml index 9326be25fa83..837d2a1a840f 100644 --- a/mmv1/products/datastore/product.yaml +++ b/mmv1/products/datastore/product.yaml @@ -19,6 +19,10 @@ versions: base_url: https://datastore.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/datastore +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Datastore API + url: https://console.cloud.google.com/apis/library/datastore.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/datastream/product.yaml b/mmv1/products/datastream/product.yaml index db9e4a5a5af5..d5a3f720158d 100644 --- a/mmv1/products/datastream/product.yaml +++ b/mmv1/products/datastream/product.yaml @@ -19,6 +19,10 @@ versions: base_url: https://datastream.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Datastream API + url: https://console.cloud.google.com/apis/library/datastream.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/deploymentmanager/product.yaml b/mmv1/products/deploymentmanager/product.yaml index 119dd6f312f2..3fe1235ed41f 100644 --- a/mmv1/products/deploymentmanager/product.yaml +++ b/mmv1/products/deploymentmanager/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://www.googleapis.com/deploymentmanager/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Deployment Manager API + url: https://console.cloud.google.com/apis/library/deploymentmanager.googleapis.com/ diff --git a/mmv1/products/dialogflow/product.yaml b/mmv1/products/dialogflow/product.yaml index b071ad685efd..234d46d7597e 100644 --- a/mmv1/products/dialogflow/product.yaml +++ b/mmv1/products/dialogflow/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://dialogflow.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Dialogflow API + url: https://console.cloud.google.com/apis/library/dialogflow.googleapis.com diff --git a/mmv1/products/dialogflowcx/product.yaml b/mmv1/products/dialogflowcx/product.yaml index 67a46f177180..620bc0c296c9 100644 --- a/mmv1/products/dialogflowcx/product.yaml +++ b/mmv1/products/dialogflowcx/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://{{location}}-dialogflow.googleapis.com/v3/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Dialogflow API + url: https://console.cloud.google.com/apis/library/dialogflow.googleapis.com diff --git a/mmv1/products/dns/product.yaml b/mmv1/products/dns/product.yaml index b2c51b1cdfa4..e52c4bd86d18 100644 --- a/mmv1/products/dns/product.yaml +++ b/mmv1/products/dns/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://dns.googleapis.com/dns/v1beta2/ scopes: - https://www.googleapis.com/auth/ndev.clouddns.readwrite +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Cloud DNS API + url: https://console.cloud.google.com/apis/library/dns.googleapis.com/ diff --git a/mmv1/products/documentai/product.yaml b/mmv1/products/documentai/product.yaml index 27c16a6a1a8d..c4de1f3c2903 100644 --- a/mmv1/products/documentai/product.yaml +++ b/mmv1/products/documentai/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://{{location}}-documentai.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Document AI API + url: https://console.cloud.google.com/apis/api/documentai.googleapis.com/overview diff --git a/mmv1/products/documentaiwarehouse/product.yaml b/mmv1/products/documentaiwarehouse/product.yaml index cf1bca6a298c..5493a6660cb2 100644 --- a/mmv1/products/documentaiwarehouse/product.yaml +++ b/mmv1/products/documentaiwarehouse/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://contentwarehouse.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Document AI Warehouse API + url: https://console.cloud.google.com/apis/library/contentwarehouse.googleapis.com/ diff --git a/mmv1/products/essentialcontacts/product.yaml b/mmv1/products/essentialcontacts/product.yaml index b8b67e02b161..9664e3fc0bec 100644 --- a/mmv1/products/essentialcontacts/product.yaml +++ b/mmv1/products/essentialcontacts/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://essentialcontacts.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Essential Contacts API + url: https://console.cloud.google.com/apis/api/essentialcontacts.googleapis.com/overview diff --git a/mmv1/products/firebasedatabase/product.yaml b/mmv1/products/firebasedatabase/product.yaml index 29d4d27545c3..3352fdee1b3f 100644 --- a/mmv1/products/firebasedatabase/product.yaml +++ b/mmv1/products/firebasedatabase/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://firebasedatabase.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Firebase Realtime Database API + url: https://console.cloud.google.com/apis/library/firebasedatabase.googleapis.com/ diff --git a/mmv1/products/firebaseextensions/product.yaml b/mmv1/products/firebaseextensions/product.yaml index fc53a7e667dd..c63efe3bbf20 100644 --- a/mmv1/products/firebaseextensions/product.yaml +++ b/mmv1/products/firebaseextensions/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://firebaseextensions.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Firebase Extensions API + url: https://console.cloud.google.com/apis/library/firebaseextensions.googleapis.com/ diff --git a/mmv1/products/firestore/product.yaml b/mmv1/products/firestore/product.yaml index ddf124162d59..1f5a68462689 100644 --- a/mmv1/products/firestore/product.yaml +++ b/mmv1/products/firestore/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://firestore.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Firestore API + url: https://console.cloud.google.com/apis/library/firestore.googleapis.com diff --git a/mmv1/products/gkebackup/product.yaml b/mmv1/products/gkebackup/product.yaml index ba858ce19ed3..243ef5390b52 100644 --- a/mmv1/products/gkebackup/product.yaml +++ b/mmv1/products/gkebackup/product.yaml @@ -40,3 +40,7 @@ async: !ruby/object:Api::OpAsync error: !ruby/object:Api::OpAsync::Error path: 'error' message: 'message' +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Backup for GKE API + url: https://console.cloud.google.com/apis/library/gkebackup.googleapis.com diff --git a/mmv1/products/gkehub/product.yaml b/mmv1/products/gkehub/product.yaml index 7de11c5f4842..bc9bebbe7800 100644 --- a/mmv1/products/gkehub/product.yaml +++ b/mmv1/products/gkehub/product.yaml @@ -24,3 +24,7 @@ versions: base_url: https://gkehub.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: GKEHub API + url: https://console.cloud.google.com/apis/library/gkehub.googleapis.com diff --git a/mmv1/products/gkehub2/product.yaml b/mmv1/products/gkehub2/product.yaml index 649e6246c4a1..1cdc7430a937 100644 --- a/mmv1/products/gkehub2/product.yaml +++ b/mmv1/products/gkehub2/product.yaml @@ -24,3 +24,7 @@ versions: base_url: https://gkehub.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: GKEHub API + url: https://console.cloud.google.com/apis/library/gkehub.googleapis.com diff --git a/mmv1/products/gkeonprem/product.yaml b/mmv1/products/gkeonprem/product.yaml index bd5b71a26eac..6027ecb665ec 100644 --- a/mmv1/products/gkeonprem/product.yaml +++ b/mmv1/products/gkeonprem/product.yaml @@ -20,6 +20,10 @@ versions: base_url: https://gkeonprem.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Anthos On-Prem API + url: https://console.cloud.google.com/apis/library/gkeonprem.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation kind: 'gkeonprem#operation' diff --git a/mmv1/products/healthcare/product.yaml b/mmv1/products/healthcare/product.yaml index 98d508c164a6..b75131d30f7d 100644 --- a/mmv1/products/healthcare/product.yaml +++ b/mmv1/products/healthcare/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://healthcare.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Healthcare API + url: https://console.cloud.google.com/apis/library/healthcare.googleapis.com/ diff --git a/mmv1/products/iam2/product.yaml b/mmv1/products/iam2/product.yaml index 7911ba2a12ab..c856f35dea6d 100644 --- a/mmv1/products/iam2/product.yaml +++ b/mmv1/products/iam2/product.yaml @@ -24,6 +24,10 @@ versions: base_url: https://iam.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/iam +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Identity and Access Management (IAM) API + url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/iambeta/product.yaml b/mmv1/products/iambeta/product.yaml index 55786f97e1ec..284843a60d2c 100644 --- a/mmv1/products/iambeta/product.yaml +++ b/mmv1/products/iambeta/product.yaml @@ -24,6 +24,10 @@ versions: base_url: https://iam.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/iam +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Identity and Access Management (IAM) API + url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/iamworkforcepool/product.yaml b/mmv1/products/iamworkforcepool/product.yaml index fb48c144d241..65b859518531 100644 --- a/mmv1/products/iamworkforcepool/product.yaml +++ b/mmv1/products/iamworkforcepool/product.yaml @@ -24,6 +24,10 @@ versions: base_url: https://iam.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/iam +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Identity and Access Management (IAM) API + url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/iap/product.yaml b/mmv1/products/iap/product.yaml index 6fbf8a2fbddc..851b68d1743c 100644 --- a/mmv1/products/iap/product.yaml +++ b/mmv1/products/iap/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://iap.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Identity-Aware Proxy + url: https://console.cloud.google.com/apis/library/iap.googleapis.com/ diff --git a/mmv1/products/identityplatform/product.yaml b/mmv1/products/identityplatform/product.yaml index 6a7766e64e11..c5ae1a8e323e 100644 --- a/mmv1/products/identityplatform/product.yaml +++ b/mmv1/products/identityplatform/product.yaml @@ -22,3 +22,7 @@ scopes: - https://www.googleapis.com/auth/identitytoolkit - https://www.googleapis.com/auth/firebase - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Identity Platform + url: https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity/ diff --git a/mmv1/products/kms/product.yaml b/mmv1/products/kms/product.yaml index 17295cea22e2..d49d04acc121 100644 --- a/mmv1/products/kms/product.yaml +++ b/mmv1/products/kms/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://cloudkms.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloudkms +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Key Management Service (KMS) API + url: https://console.cloud.google.com/apis/library/cloudkms.googleapis.com/ diff --git a/mmv1/products/logging/product.yaml b/mmv1/products/logging/product.yaml index e017f3f7f9e9..7e94a7db0860 100644 --- a/mmv1/products/logging/product.yaml +++ b/mmv1/products/logging/product.yaml @@ -19,3 +19,7 @@ versions: base_url: https://logging.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Stackdriver Logging API + url: https://console.cloud.google.com/apis/library/logging.googleapis.com/ diff --git a/mmv1/products/looker/product.yaml b/mmv1/products/looker/product.yaml index 39e6e9cd2e88..4d3d1aba79e1 100644 --- a/mmv1/products/looker/product.yaml +++ b/mmv1/products/looker/product.yaml @@ -20,6 +20,10 @@ versions: base_url: https://looker.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Looker API + url: https://console.cloud.google.com/apis/library/looker.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/metastore/product.yaml b/mmv1/products/metastore/product.yaml index 83eb3d87cb9d..8e3a29fdf9b9 100644 --- a/mmv1/products/metastore/product.yaml +++ b/mmv1/products/metastore/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://metastore.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Dataproc Metastore API + url: https://console.cloud.google.com/apis/library/metastore.googleapis.com diff --git a/mmv1/products/mlengine/product.yaml b/mmv1/products/mlengine/product.yaml index 88f09f7fe10c..a22ed3adcf55 100644 --- a/mmv1/products/mlengine/product.yaml +++ b/mmv1/products/mlengine/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://ml.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud ML + url: https://console.cloud.google.com/apis/library/ml.googleapis.com diff --git a/mmv1/products/monitoring/product.yaml b/mmv1/products/monitoring/product.yaml index 96e9992f5774..deb7651d44fa 100644 --- a/mmv1/products/monitoring/product.yaml +++ b/mmv1/products/monitoring/product.yaml @@ -19,3 +19,7 @@ versions: base_url: https://monitoring.googleapis.com/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Stackdriver Monitoring API + url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com/ diff --git a/mmv1/products/networkconnectivity/product.yaml b/mmv1/products/networkconnectivity/product.yaml index 6bea6bf40b70..05c5bc0c3b44 100644 --- a/mmv1/products/networkconnectivity/product.yaml +++ b/mmv1/products/networkconnectivity/product.yaml @@ -20,3 +20,7 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://networkconnectivity.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Network Connectivity API + url: https://console.cloud.google.com/apis/library/networkconnectivity.googleapis.com/ diff --git a/mmv1/products/networkmanagement/product.yaml b/mmv1/products/networkmanagement/product.yaml index 63cc98193499..90d8be0e69ba 100644 --- a/mmv1/products/networkmanagement/product.yaml +++ b/mmv1/products/networkmanagement/product.yaml @@ -20,6 +20,10 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://networkmanagement.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Network Management API + url: https://console.cloud.google.com/apis/library/networkmanagement.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/networksecurity/product.yaml b/mmv1/products/networksecurity/product.yaml index 0d308e900f86..85ae621d8459 100644 --- a/mmv1/products/networksecurity/product.yaml +++ b/mmv1/products/networksecurity/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://networksecurity.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Network Security API + url: https://console.cloud.google.com/apis/library/networksecurity.googleapis.com diff --git a/mmv1/products/networkservices/product.yaml b/mmv1/products/networkservices/product.yaml index fc962b336f27..38556fd15847 100644 --- a/mmv1/products/networkservices/product.yaml +++ b/mmv1/products/networkservices/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://networkservices.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-identity +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Network Services API + url: https://console.cloud.google.com/apis/library/networkservices.googleapis.com diff --git a/mmv1/products/notebooks/product.yaml b/mmv1/products/notebooks/product.yaml index 50d80716e490..179553c8f5a9 100644 --- a/mmv1/products/notebooks/product.yaml +++ b/mmv1/products/notebooks/product.yaml @@ -27,6 +27,10 @@ versions: base_url: https://notebooks.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Notebooks API + url: https://console.cloud.google.com/apis/api/notebooks.googleapis.com async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation base_url: '{{op_id}}' diff --git a/mmv1/products/orgpolicy/product.yaml b/mmv1/products/orgpolicy/product.yaml index c0f0540f562e..993a7c05c26d 100644 --- a/mmv1/products/orgpolicy/product.yaml +++ b/mmv1/products/orgpolicy/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://orgpolicy.googleapis.com/v2/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Organization Policy API + url: https://console.cloud.google.com/apis/api/orgpolicy.googleapis.com/overview diff --git a/mmv1/products/osconfig/product.yaml b/mmv1/products/osconfig/product.yaml index 01d74be2526f..e922b75bfacf 100644 --- a/mmv1/products/osconfig/product.yaml +++ b/mmv1/products/osconfig/product.yaml @@ -21,6 +21,10 @@ versions: - !ruby/object:Api::Product::Version name: beta base_url: https://osconfig.googleapis.com/v1beta/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Identity and Access Management (IAM) API + url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ scopes: - https://www.googleapis.com/auth/cloud-platform - https://www.googleapis.com/auth/compute diff --git a/mmv1/products/oslogin/product.yaml b/mmv1/products/oslogin/product.yaml index 62498a0f9bd6..8aedca5e8727 100644 --- a/mmv1/products/oslogin/product.yaml +++ b/mmv1/products/oslogin/product.yaml @@ -18,6 +18,10 @@ versions: - !ruby/object:Api::Product::Version name: ga base_url: https://oslogin.googleapis.com/v1/ +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Identity and Access Management (IAM) API + url: https://console.cloud.google.com/apis/library/iam.googleapis.com/ scopes: - https://www.googleapis.com/auth/cloud-platform - https://www.googleapis.com/auth/compute diff --git a/mmv1/products/privateca/product.yaml b/mmv1/products/privateca/product.yaml index d310b6591787..11bf7804df5c 100644 --- a/mmv1/products/privateca/product.yaml +++ b/mmv1/products/privateca/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://privateca.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Certificate Authority API + url: https://console.cloud.google.com/apis/api/privateca.googleapis.com diff --git a/mmv1/products/publicca/product.yaml b/mmv1/products/publicca/product.yaml index 6243c8d6c677..ea8152a52141 100644 --- a/mmv1/products/publicca/product.yaml +++ b/mmv1/products/publicca/product.yaml @@ -22,3 +22,7 @@ versions: base_url: https://publicca.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Public Certificate Authority API + url: https://console.cloud.google.com/apis/library/publicca.googleapis.com diff --git a/mmv1/products/pubsub/product.yaml b/mmv1/products/pubsub/product.yaml index fee2f465bb07..f63d92f5d171 100644 --- a/mmv1/products/pubsub/product.yaml +++ b/mmv1/products/pubsub/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://pubsub.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/pubsub +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Pub/Sub API + url: https://console.cloud.google.com/apis/library/pubsub.googleapis.com/ diff --git a/mmv1/products/pubsublite/product.yaml b/mmv1/products/pubsublite/product.yaml index 48e342b3ae62..236999876cb6 100644 --- a/mmv1/products/pubsublite/product.yaml +++ b/mmv1/products/pubsublite/product.yaml @@ -21,3 +21,7 @@ versions: cai_base_url: https://pubsublite.googleapis.com/v1/admin/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Pub/Sub Lite API + url: https://console.cloud.google.com/apis/library/pubsublite.googleapis.com/ diff --git a/mmv1/products/resourcemanager/product.yaml b/mmv1/products/resourcemanager/product.yaml index f7ccd2fa3826..33569faf075f 100644 --- a/mmv1/products/resourcemanager/product.yaml +++ b/mmv1/products/resourcemanager/product.yaml @@ -21,3 +21,7 @@ versions: scopes: # All access is needed to create projects. - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Resource Manager API + url: https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com/ diff --git a/mmv1/products/runtimeconfig/product.yaml b/mmv1/products/runtimeconfig/product.yaml index 0f5f582cdb8b..9d7cbf6db3e5 100644 --- a/mmv1/products/runtimeconfig/product.yaml +++ b/mmv1/products/runtimeconfig/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://runtimeconfig.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloudruntimeconfig +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Resource Manager API + url: https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com/ diff --git a/mmv1/products/secretmanager/product.yaml b/mmv1/products/secretmanager/product.yaml index e08b510702c9..a94a4f7e74cc 100644 --- a/mmv1/products/secretmanager/product.yaml +++ b/mmv1/products/secretmanager/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://secretmanager.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Secret Manager API + url: https://console.cloud.google.com/apis/library/secretmanager.googleapis.com/ diff --git a/mmv1/products/securityscanner/product.yaml b/mmv1/products/securityscanner/product.yaml index 20f8504a48c3..928368b06b9f 100644 --- a/mmv1/products/securityscanner/product.yaml +++ b/mmv1/products/securityscanner/product.yaml @@ -19,3 +19,7 @@ versions: base_url: https://websecurityscanner.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Web Security Scanner API + url: https://console.cloud.google.com/apis/library/websecurityscanner.googleapis.com/ diff --git a/mmv1/products/servicedirectory/product.yaml b/mmv1/products/servicedirectory/product.yaml index 964241bcf264..2fc20e6f77fd 100644 --- a/mmv1/products/servicedirectory/product.yaml +++ b/mmv1/products/servicedirectory/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://servicedirectory.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Service Directory API + url: https://console.cloud.google.com/apis/library/servicedirectory.googleapis.com/ diff --git a/mmv1/products/servicemanagement/product.yaml b/mmv1/products/servicemanagement/product.yaml index 6152d8382140..cb3cc794a3eb 100644 --- a/mmv1/products/servicemanagement/product.yaml +++ b/mmv1/products/servicemanagement/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://servicemanagement.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloudplatform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Service Management API + url: https://console.cloud.google.com/apis/library/servicemanagement.googleapis.com/ diff --git a/mmv1/products/serviceusage/product.yaml b/mmv1/products/serviceusage/product.yaml index 27e40852210e..36672796aab6 100644 --- a/mmv1/products/serviceusage/product.yaml +++ b/mmv1/products/serviceusage/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://serviceusage.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Service Usage API + url: https://console.cloud.google.com/apis/library/serviceusage.googleapis.com/ diff --git a/mmv1/products/sourcerepo/product.yaml b/mmv1/products/sourcerepo/product.yaml index e78f0569cd34..d4717e5d1258 100644 --- a/mmv1/products/sourcerepo/product.yaml +++ b/mmv1/products/sourcerepo/product.yaml @@ -21,3 +21,7 @@ versions: base_url: https://sourcerepo.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Source Repositories API + url: https://console.cloud.google.com/apis/library/sourcerepo.googleapis.com/ diff --git a/mmv1/products/spanner/product.yaml b/mmv1/products/spanner/product.yaml index 883226d15cd3..87e0f1204e19 100644 --- a/mmv1/products/spanner/product.yaml +++ b/mmv1/products/spanner/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://spanner.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/spanner.admin +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Spanner API + url: https://console.cloud.google.com/apis/library/spanner.googleapis.com/ diff --git a/mmv1/products/sql/product.yaml b/mmv1/products/sql/product.yaml index 5658ae7e1975..42fdd7a2100d 100644 --- a/mmv1/products/sql/product.yaml +++ b/mmv1/products/sql/product.yaml @@ -21,6 +21,10 @@ versions: base_url: https://sqladmin.googleapis.com/sql/v1beta4/ scopes: - https://www.googleapis.com/auth/sqlservice.admin +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud SQL Admin API + url: https://console.cloud.google.com/apis/library/sqladmin.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation kind: 'sql#operation' diff --git a/mmv1/products/storage/product.yaml b/mmv1/products/storage/product.yaml index 458a2e7f5e19..4d380b12ef79 100644 --- a/mmv1/products/storage/product.yaml +++ b/mmv1/products/storage/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://storage.googleapis.com/storage/v1/ scopes: - https://www.googleapis.com/auth/devstorage.full_control +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Storage + url: https://console.cloud.google.com/apis/library/storage-component.googleapis.com/ diff --git a/mmv1/products/storageinsights/product.yaml b/mmv1/products/storageinsights/product.yaml index e43481d0e456..7f7a0b22e93c 100644 --- a/mmv1/products/storageinsights/product.yaml +++ b/mmv1/products/storageinsights/product.yaml @@ -20,3 +20,10 @@ versions: base_url: https://storageinsights.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/devstorage.full_control +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Storage + url: https://console.cloud.google.com/apis/library/storage-component.googleapis.com/ + - !ruby/object:Api::Product::ApiReference + name: Google Cloud Storage Insights + url: https://console.cloud.google.com/apis/library/storageinsights.googleapis.com/ diff --git a/mmv1/products/storagetransfer/product.yaml b/mmv1/products/storagetransfer/product.yaml index 62d3765c7a91..31709ea7c94c 100644 --- a/mmv1/products/storagetransfer/product.yaml +++ b/mmv1/products/storagetransfer/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://storagetransfer.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Storage Transfer API + url: https://console.cloud.google.com/apis/library/storagetransfer.googleapis.com/ diff --git a/mmv1/products/vmwareengine/product.yaml b/mmv1/products/vmwareengine/product.yaml index f55c85d8bced..5d6e08562005 100644 --- a/mmv1/products/vmwareengine/product.yaml +++ b/mmv1/products/vmwareengine/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://vmwareengine.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: VMwareEngine API + url: https://console.cloud.google.com/apis/library/vmwareengine.googleapis.com/ diff --git a/mmv1/products/vpcaccess/product.yaml b/mmv1/products/vpcaccess/product.yaml index ff79d8e6791e..86e93dcd1a99 100644 --- a/mmv1/products/vpcaccess/product.yaml +++ b/mmv1/products/vpcaccess/product.yaml @@ -23,3 +23,7 @@ versions: base_url: https://vpcaccess.googleapis.com/v1beta1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Serverless VPC Access API + url: https://console.cloud.google.com/apis/library/vpcaccess.googleapis.com/ diff --git a/mmv1/products/workflows/product.yaml b/mmv1/products/workflows/product.yaml index f014e8edd8ae..2f84e8ef20d4 100644 --- a/mmv1/products/workflows/product.yaml +++ b/mmv1/products/workflows/product.yaml @@ -23,6 +23,10 @@ versions: base_url: https://workflows.googleapis.com/v1/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Workflows API + url: https://console.cloud.google.com/apis/library/workflows.googleapis.com/ async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' diff --git a/mmv1/products/workstations/product.yaml b/mmv1/products/workstations/product.yaml index f219cbb130ad..751e8051212b 100644 --- a/mmv1/products/workstations/product.yaml +++ b/mmv1/products/workstations/product.yaml @@ -20,3 +20,7 @@ versions: base_url: https://workstations.googleapis.com/v1beta/ scopes: - https://www.googleapis.com/auth/cloud-platform +apis_required: + - !ruby/object:Api::Product::ApiReference + name: Cloud Workstations API + url: https://console.cloud.google.com/apis/library/workstations.googleapis.com From e3d81f8f3a9fb6ba3ca4e69cf879ff3aecb47276 Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Thu, 14 Sep 2023 17:40:36 +0000 Subject: [PATCH 069/476] Merge base branch before running rake tests (#8934) * Merge base branch before running rake tests * Fetch depth 2 --- .github/workflows/magic-modules.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/magic-modules.yml b/.github/workflows/magic-modules.yml index a6596c6ce5c1..1a2c88510fa2 100644 --- a/.github/workflows/magic-modules.yml +++ b/.github/workflows/magic-modules.yml @@ -39,6 +39,15 @@ jobs: uses: actions/checkout@v3 with: path: repo + fetch-depth: 2 + - name: Merge base branch + id: pull_request + run: | + cd repo + git config user.name "modular-magician" + git config user.email "magic-modules@google.com" + git fetch origin ${{ github.base_ref }} # Fetch the base branch + git merge --no-ff origin/${{ github.base_ref }} # Merge with the base branch - name: Set up Ruby uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1 with: From aaccd4a21efbeea76b3573d2e40aac50e40dbb6a Mon Sep 17 00:00:00 2001 From: Sarah French <15078782+SarahFrench@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:59:10 +0100 Subject: [PATCH 070/476] Make plugin-framework provider configuration code treat empty values like the SDK (#8798) * Make PF config code change `project = ""` to null value before checking ENVs * Make plugin framework config code change all empty strings in config to null values * Fix defect in unit test for `project`, uncomment * Uncomment empty string unit tests * Fix defect in test; expeceted value should be null list * Add handling of empty lists in `HandleZeroValues` * Fix typo in comment * Add test case asserting `impersonate_service_account` empty strings are overridden by an ENV * Update SDK `batching` tests: rename test cases, make it clear values are arbitary * Update `HandleZeroValues` to handle `batching` argument * Uncomment empty string test * Change test inputs from 123s to 45s This is because 123s is transformed to 2m3s, but 45s remains 45s * Protect against Batching being null/unknown in `HandleZeroValues` * Add non-VCR acceptance test that shows provider behaviour when `credentials=""` and `GOOGLE_CREDENTIALS` interact --- .../fwtransport/framework_config.go.erb | 82 +++++ .../fwtransport/framework_config_test.go.erb | 284 +++++++++--------- .../provider/provider_internal_test.go | 20 +- .../terraform/provider/provider_test.go.erb | 71 ++++- 4 files changed, 309 insertions(+), 148 deletions(-) diff --git a/mmv1/third_party/terraform/fwtransport/framework_config.go.erb b/mmv1/third_party/terraform/fwtransport/framework_config.go.erb index 51398eddc1de..6c7d1ad64dc4 100644 --- a/mmv1/third_party/terraform/fwtransport/framework_config.go.erb +++ b/mmv1/third_party/terraform/fwtransport/framework_config.go.erb @@ -17,6 +17,7 @@ import ( "google.golang.org/grpc" "github.com/hashicorp/go-cleanhttp" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" @@ -55,6 +56,16 @@ type FrameworkProviderConfig struct { // LoadAndValidateFramework handles the bulk of configuring the provider // it is pulled out so that we can manually call this from our testing provider as well func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context, data *fwmodels.ProviderModel, tfVersion string, diags *diag.Diagnostics, providerversion string) { + + + // Make the plugin framwork code behave like the SDK by ignoring zero values. This means re-setting zero values to null. + // This is added to fix https://github.com/hashicorp/terraform-provider-google/issues/14255 in a v4.x.x release + // TODO(SarahFrench) remove as part of https://github.com/hashicorp/terraform-provider-google/issues/14447 in 5.0.0 + p.HandleZeroValues(ctx, data, diags) + if diags.HasError() { + return + } + // Set defaults if needed p.HandleDefaults(ctx, data, diags) if diags.HasError() { @@ -104,6 +115,77 @@ func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context, p.RequestBatcherIam = transport_tpg.NewRequestBatcher("IAM", ctx, batchingConfig) } +// HandleZeroValues will make the plugin framework act like the SDK; zero value, particularly empty strings, are converted to null. +// This causes the plugin framework to treat the field as unset, just like how the SDK ignores empty strings. +func (p *FrameworkProviderConfig) HandleZeroValues(ctx context.Context, data *fwmodels.ProviderModel, diags *diag.Diagnostics) { + + // Change empty strings to null values + if data.AccessToken.Equal(types.StringValue("")) { + data.AccessToken = types.StringNull() + } + if data.BillingProject.Equal(types.StringValue("")) { + data.BillingProject = types.StringNull() + } + if data.Credentials.Equal(types.StringValue("")) { + data.Credentials = types.StringNull() + } + if data.ImpersonateServiceAccount.Equal(types.StringValue("")) { + data.ImpersonateServiceAccount = types.StringNull() + } + if data.Project.Equal(types.StringValue("")) { + data.Project = types.StringNull() + } + if data.Region.Equal(types.StringValue("")) { + data.Region = types.StringNull() + } + if data.RequestReason.Equal(types.StringValue("")) { + data.RequestReason = types.StringNull() + } + if data.RequestTimeout.Equal(types.StringValue("")) { + data.RequestTimeout = types.StringNull() + } + if data.Zone.Equal(types.StringValue("")) { + data.Zone = types.StringNull() + } + + // Change lists that aren't null or unknown with length of zero to null lists + if !data.Scopes.IsNull() && !data.Scopes.IsUnknown() && (len(data.Scopes.Elements()) == 0) { + data.Scopes = types.ListNull(types.StringType) + } + if !data.ImpersonateServiceAccountDelegates.IsNull() && !data.ImpersonateServiceAccountDelegates.IsUnknown() && (len(data.ImpersonateServiceAccountDelegates.Elements()) == 0) { + data.ImpersonateServiceAccountDelegates = types.ListNull(types.StringType) + } + + // Batching implementation will change in future, but this code will be removed in 5.0.0 so may be unaffected + if !data.Batching.IsNull() && !data.Batching.IsUnknown() && (len(data.Batching.Elements()) > 0) { + var pbConfigs []fwmodels.ProviderBatching + d := data.Batching.ElementsAs(ctx, &pbConfigs, true) + diags.Append(d...) + if diags.HasError() { + return + } + if pbConfigs[0].SendAfter.Equal(types.StringValue("")) { + pbConfigs[0].SendAfter = types.StringNull() // Convert empty string to null + } + b, _ := types.ObjectValue( + map[string]attr.Type{ + "enable_batching": types.BoolType, + "send_after": types.StringType, + }, + map[string]attr.Value{ + "enable_batching": pbConfigs[0].EnableBatching, + "send_after": pbConfigs[0].SendAfter, + }, + ) + newBatching, d := types.ListValue(types.ObjectType{}.WithAttributeTypes(fwmodels.ProviderBatchingAttributes), []attr.Value{b}) + diags.Append(d...) + if diags.HasError() { + return + } + data.Batching = newBatching + } +} + // HandleDefaults will handle all the defaults necessary in the provider func (p *FrameworkProviderConfig) HandleDefaults(ctx context.Context, data *fwmodels.ProviderModel, diags *diag.Diagnostics) { if data.AccessToken.IsNull() && data.Credentials.IsNull() { diff --git a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb index a92cfdc70f49..5569da181fc8 100644 --- a/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb +++ b/mmv1/third_party/terraform/fwtransport/framework_config_test.go.erb @@ -102,24 +102,23 @@ func TestFrameworkProvider_LoadAndValidateFramework_project(t *testing.T) { ExpectedConfigStructValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when project is set as an empty string the field is treated as if it's unset, without error": { - // ConfigValues: fwmodels.ProviderModel{ - // Project: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringNull(), - // ExpectedConfigStructValue: types.StringNull(), - // }, - // "when project is set as an empty string an environment variable will be used": { - // ConfigValues: fwmodels.ProviderModel{ - // Project: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "GOOGLE_PROJECT": "project-from-GOOGLE_PROJECT", - // }, - // ExpectedDataModelValue: types.StringNull(), - // ExpectedConfigStructValue: types.StringValue("project-from-GOOGLE_PROJECT"), - // }, + "when project is set as an empty string the field is treated as if it's unset, without error": { + ConfigValues: fwmodels.ProviderModel{ + Project: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringNull(), + ExpectedConfigStructValue: types.StringNull(), + }, + "when project is set as an empty string an environment variable will be used": { + ConfigValues: fwmodels.ProviderModel{ + Project: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_PROJECT": "project-from-GOOGLE_PROJECT", + }, + ExpectedDataModelValue: types.StringValue("project-from-GOOGLE_PROJECT"), + ExpectedConfigStructValue: types.StringValue("project-from-GOOGLE_PROJECT"), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when project is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -264,16 +263,15 @@ func TestFrameworkProvider_LoadAndValidateFramework_credentials(t *testing.T) { ExpectedDataModelValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when credentials is set to an empty string in the config (and access_token unset), GOOGLE_APPLICATION_CREDENTIALS is used": { - // ConfigValues: fwmodels.ProviderModel{ - // Credentials: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "GOOGLE_APPLICATION_CREDENTIALS": transport_tpg.TestFakeCredentialsPath, // needs to be a path to a file when used by code - // }, - // ExpectedDataModelValue: types.StringNull(), - // }, + "when credentials is set to an empty string in the config (and access_token unset), GOOGLE_APPLICATION_CREDENTIALS is used": { + ConfigValues: fwmodels.ProviderModel{ + Credentials: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_APPLICATION_CREDENTIALS": transport_tpg.TestFakeCredentialsPath, // needs to be a path to a file when used by code + }, + ExpectedDataModelValue: types.StringNull(), + }, // NOTE: these tests can't run in Cloud Build due to ADC locating credentials despite `GOOGLE_APPLICATION_CREDENTIALS` being unset // See https://cloud.google.com/docs/authentication/application-default-credentials#search_order // Also, when running these tests locally you need to run `gcloud auth application-default revoke` to ensure your machine isn't supplying ADCs @@ -434,23 +432,23 @@ func TestFrameworkProvider_LoadAndValidateFramework_billingProject(t *testing.T) ExpectedConfigStructValue: types.StringNull(), }, // Handling empty strings in config - // "when billing_project is set as an empty string the field is treated as if it's unset, without error": { - // ConfigValues: fwmodels.ProviderModel{ - // BillingProject: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringNull(), - // ExpectedConfigStructValue: types.StringNull(), - // }, - // "when billing_project is set as an empty string an environment variable will be used": { - // ConfigValues: fwmodels.ProviderModel{ - // BillingProject: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "GOOGLE_BILLING_PROJECT": "billing-project-from-env", - // }, - // ExpectedDataModelValue: types.StringValue("billing-project-from-env"), - // ExpectedConfigStructValue: types.StringValue("billing-project-from-env"), - // }, + "when billing_project is set as an empty string the field is treated as if it's unset, without error": { + ConfigValues: fwmodels.ProviderModel{ + BillingProject: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringNull(), + ExpectedConfigStructValue: types.StringNull(), + }, + "when billing_project is set as an empty string an environment variable will be used": { + ConfigValues: fwmodels.ProviderModel{ + BillingProject: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_BILLING_PROJECT": "billing-project-from-env", + }, + ExpectedDataModelValue: types.StringValue("billing-project-from-env"), + ExpectedConfigStructValue: types.StringValue("billing-project-from-env"), + }, } for tn, tc := range cases { @@ -549,24 +547,23 @@ func TestFrameworkProvider_LoadAndValidateFramework_region(t *testing.T) { ExpectedConfigStructValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when region is set as an empty string the field is treated as if it's unset, without error": { - // ConfigValues: fwmodels.ProviderModel{ - // Region: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringNull(), - // ExpectedConfigStructValue: types.StringNull(), - // }, - // "when region is set as an empty string an environment variable will be used": { - // ConfigValues: fwmodels.ProviderModel{ - // Region: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "GOOGLE_REGION": "region-from-env", - // }, - // ExpectedDataModelValue: types.StringValue("region-from-env"), - // ExpectedConfigStructValue: types.StringValue("region-from-env"), - // }, + "when region is set as an empty string the field is treated as if it's unset, without error": { + ConfigValues: fwmodels.ProviderModel{ + Region: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringNull(), + ExpectedConfigStructValue: types.StringNull(), + }, + "when region is set as an empty string an environment variable will be used": { + ConfigValues: fwmodels.ProviderModel{ + Region: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_REGION": "region-from-env", + }, + ExpectedDataModelValue: types.StringValue("region-from-env"), + ExpectedConfigStructValue: types.StringValue("region-from-env"), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when region is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -698,24 +695,23 @@ func TestFrameworkProvider_LoadAndValidateFramework_zone(t *testing.T) { ExpectedConfigStructValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when zone is set as an empty string the field is treated as if it's unset, without error": { - // ConfigValues: fwmodels.ProviderModel{ - // Zone: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringNull(), - // ExpectedConfigStructValue: types.StringNull(), - // }, - // "when zone is set as an empty string an environment variable will be used": { - // ConfigValues: fwmodels.ProviderModel{ - // Zone: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "GOOGLE_ZONE": "zone-from-env", - // }, - // ExpectedDataModelValue: types.StringValue("zone-from-env"), - // ExpectedConfigStructValue: types.StringValue("zone-from-env"), - // }, + "when zone is set as an empty string the field is treated as if it's unset, without error": { + ConfigValues: fwmodels.ProviderModel{ + Zone: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringNull(), + ExpectedConfigStructValue: types.StringNull(), + }, + "when zone is set as an empty string an environment variable will be used": { + ConfigValues: fwmodels.ProviderModel{ + Zone: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_ZONE": "zone-from-env", + }, + ExpectedDataModelValue: types.StringValue("zone-from-env"), + ExpectedConfigStructValue: types.StringValue("zone-from-env"), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when zone is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -814,23 +810,22 @@ func TestFrameworkProvider_LoadAndValidateFramework_accessToken(t *testing.T) { ExpectedDataModelValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when access_token is set as an empty string the field is treated as if it's unset, without error (as long as credentials supplied in its absence)": { - // ConfigValues: fwmodels.ProviderModel{ - // AccessToken: types.StringValue(""), - // Credentials: types.StringValue(transport_tpg.TestFakeCredentialsPath), - // }, - // ExpectedDataModelValue: types.StringNull(), - // }, - // "when access_token is set as an empty string in the config, an environment variable is used": { - // ConfigValues: fwmodels.ProviderModel{ - // AccessToken: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "GOOGLE_OAUTH_ACCESS_TOKEN": "value-from-GOOGLE_OAUTH_ACCESS_TOKEN", - // }, - // ExpectedDataModelValue: types.StringValue("value-from-GOOGLE_OAUTH_ACCESS_TOKEN"), - // }, + "when access_token is set as an empty string the field is treated as if it's unset, without error (as long as credentials supplied in its absence)": { + ConfigValues: fwmodels.ProviderModel{ + AccessToken: types.StringValue(""), + Credentials: types.StringValue(transport_tpg.TestFakeCredentialsPath), + }, + ExpectedDataModelValue: types.StringNull(), + }, + "when access_token is set as an empty string in the config, an environment variable is used": { + ConfigValues: fwmodels.ProviderModel{ + AccessToken: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_OAUTH_ACCESS_TOKEN": "value-from-GOOGLE_OAUTH_ACCESS_TOKEN", + }, + ExpectedDataModelValue: types.StringValue("value-from-GOOGLE_OAUTH_ACCESS_TOKEN"), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when access_token is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -1054,13 +1049,21 @@ func TestFrameworkProvider_LoadAndValidateFramework_impersonateServiceAccount(t ExpectedDataModelValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when impersonate_service_account is set as an empty array the field is treated as if it's unset, without error": { - // ConfigValues: fwmodels.ProviderModel{ - // ImpersonateServiceAccount: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringNull(), - // }, + "when impersonate_service_account is set as an empty string the field is treated as if it's unset, without error": { + ConfigValues: fwmodels.ProviderModel{ + ImpersonateServiceAccount: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringNull(), + }, + "when impersonate_service_account is set as an empty string in the config, an environment variable is used": { + ConfigValues: fwmodels.ProviderModel{ + ImpersonateServiceAccount: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT": "value-from-env@example.com", + }, + ExpectedDataModelValue: types.StringValue("value-from-env@example.com"), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when impersonate_service_account is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -1148,7 +1151,7 @@ func TestFrameworkProvider_LoadAndValidateFramework_impersonateServiceAccountDel // Handling empty values in config "when impersonate_service_account_delegates is set as an empty array the field is treated as if it's unset, without error": { ImpersonateServiceAccountDelegatesValue: []string{}, - ExpectedDataModelValue: []string{}, + ExpectedDataModelValue: nil, }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 @@ -1347,22 +1350,21 @@ func TestFrameworkProvider_LoadAndValidateFramework_requestReason(t *testing.T) ExpectedDataModelValue: types.StringNull(), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when request_reason is set as an empty string in the config it is overridden by environment variables": { - // ConfigValues: fwmodels.ProviderModel{ - // RequestReason: types.StringValue(""), - // }, - // EnvVariables: map[string]string{ - // "CLOUDSDK_CORE_REQUEST_REASON": "foo", - // }, - // ExpectedDataModelValue: types.StringValue("foo"), - // }, - // "when request_reason is set as an empty string in the config the field is treated as if it's unset, without error": { - // ConfigValues: fwmodels.ProviderModel{ - // RequestReason: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringNull(), - // }, + "when request_reason is set as an empty string in the config it is overridden by environment variables": { + ConfigValues: fwmodels.ProviderModel{ + RequestReason: types.StringValue(""), + }, + EnvVariables: map[string]string{ + "CLOUDSDK_CORE_REQUEST_REASON": "foo", + }, + ExpectedDataModelValue: types.StringValue("foo"), + }, + "when request_reason is set as an empty string in the config the field is treated as if it's unset, without error": { + ConfigValues: fwmodels.ProviderModel{ + RequestReason: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringNull(), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when request_timeout is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -1451,13 +1453,12 @@ func TestFrameworkProvider_LoadAndValidateFramework_requestTimeout(t *testing.T) ExpectedDataModelValue: types.StringValue("120s"), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when request_timeout is set as an empty string, the default value is 120s.": { - // ConfigValues: fwmodels.ProviderModel{ - // RequestTimeout: types.StringValue(""), - // }, - // ExpectedDataModelValue: types.StringValue("120s"), - // }, + "when request_timeout is set as an empty string, the default value is 120s.": { + ConfigValues: fwmodels.ProviderModel{ + RequestTimeout: types.StringValue(""), + }, + ExpectedDataModelValue: types.StringValue("120s"), + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when request_timeout is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -1534,9 +1535,9 @@ func TestFrameworkProvider_LoadAndValidateFramework_batching(t *testing.T) { }{ "batching can be configured with values for enable_batching and send_after": { EnableBatchingValue: types.BoolValue(true), - SendAfterValue: types.StringValue("123s"), + SendAfterValue: types.StringValue("45s"), ExpectEnableBatchingValue: types.BoolValue(true), - ExpectSendAfterValue: types.StringValue("123s"), + ExpectSendAfterValue: types.StringValue("45s"), }, "if batching is an empty block, it will set the default values for enable_batching and send_after": { // In this test, we try to create a list containing only null values @@ -1553,18 +1554,17 @@ func TestFrameworkProvider_LoadAndValidateFramework_batching(t *testing.T) { }, "when batching is configured with only send_after, enable_batching will be set to a default value": { EnableBatchingValue: types.BoolNull(), - SendAfterValue: types.StringValue("123s"), + SendAfterValue: types.StringValue("45s"), ExpectEnableBatchingValue: types.BoolValue(true), - ExpectSendAfterValue: types.StringValue("123s"), + ExpectSendAfterValue: types.StringValue("45s"), }, // Handling empty strings in config - // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14255 - // "when batching is configured with send_after as an empty string, send_after will be set to a default value": { - // EnableBatchingValue: types.BoolValue(true), - // SendAfterValue: types.StringValue(""), - // ExpectEnableBatchingValue: types.BoolValue(true), - // ExpectSendAfterValue: types.StringValue("10s"), - // }, + "when batching is configured with send_after as an empty string, send_after will be set to a default value": { + EnableBatchingValue: types.BoolValue(true), + SendAfterValue: types.StringValue(""), + ExpectEnableBatchingValue: types.BoolValue(true), + ExpectSendAfterValue: types.StringValue("10s"), // When batching block is present but has missing arguments inside, default is 10s + }, // Handling unknown values // TODO(SarahFrench) make these tests pass to address: https://github.com/hashicorp/terraform-provider-google/issues/14444 // "when batching is an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { @@ -1580,9 +1580,9 @@ func TestFrameworkProvider_LoadAndValidateFramework_batching(t *testing.T) { // }, // "when batching is configured with enable_batching as an unknown value, the provider treats it as if it's unset (align to SDK behaviour)": { // EnableBatchingValue: types.BoolNull(), - // SendAfterValue: types.StringValue("123s"), + // SendAfterValue: types.StringValue("45s"), // ExpectEnableBatchingValue: types.BoolValue(true), - // ExpectSendAfterValue: types.StringValue("123s"), + // ExpectSendAfterValue: types.StringValue("45s"), // }, // Error states "if batching is configured with send_after as an invalid value, there's an error": { diff --git a/mmv1/third_party/terraform/provider/provider_internal_test.go b/mmv1/third_party/terraform/provider/provider_internal_test.go index 37d652753cdc..27a15710ffda 100644 --- a/mmv1/third_party/terraform/provider/provider_internal_test.go +++ b/mmv1/third_party/terraform/provider/provider_internal_test.go @@ -403,7 +403,7 @@ func TestProvider_ProviderConfigure_impersonateServiceAccount(t *testing.T) { ExpectedValue: "", }, // Handling empty strings in config - "when impersonate_service_account is set as an empty array the field is treated as if it's unset, without error": { + "when impersonate_service_account is set as an empty string the field is treated as if it's unset, without error": { ConfigValues: map[string]interface{}{ "impersonate_service_account": "", "credentials": transport_tpg.TestFakeCredentialsPath, @@ -412,6 +412,16 @@ func TestProvider_ProviderConfigure_impersonateServiceAccount(t *testing.T) { ExpectFieldUnset: true, ExpectedValue: "", }, + "when impersonate_service_account is set as an empty string in the config, an environment variable is used": { + ConfigValues: map[string]interface{}{ + "impersonate_service_account": "", + "credentials": transport_tpg.TestFakeCredentialsPath, + }, + EnvVariables: map[string]string{ + "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT": "value-from-env@example.com", + }, + ExpectedValue: "value-from-env@example.com", + }, } for tn, tc := range cases { @@ -1571,12 +1581,12 @@ func TestProvider_ProviderConfigure_batching(t *testing.T) { "batching": []interface{}{ map[string]interface{}{ "enable_batching": true, - "send_after": "123s", + "send_after": "45s", }, }, }, ExpectedEnableBatchingValue: true, - ExpectedSendAfterValue: "123s", + ExpectedSendAfterValue: "45s", }, "if batching is an empty block, it will set the default values for enable_batching and send_after": { ConfigValues: map[string]interface{}{ @@ -1607,12 +1617,12 @@ func TestProvider_ProviderConfigure_batching(t *testing.T) { "credentials": transport_tpg.TestFakeCredentialsPath, "batching": []interface{}{ map[string]interface{}{ - "send_after": "123s", + "send_after": "45s", }, }, }, ExpectedEnableBatchingValue: false, - ExpectedSendAfterValue: "123s", + ExpectedSendAfterValue: "45s", }, // Error states "if batching is configured with send_after as an invalid value, there's an error": { diff --git a/mmv1/third_party/terraform/provider/provider_test.go.erb b/mmv1/third_party/terraform/provider/provider_test.go.erb index 2406a3969d41..a1676aa0621b 100644 --- a/mmv1/third_party/terraform/provider/provider_test.go.erb +++ b/mmv1/third_party/terraform/provider/provider_test.go.erb @@ -181,6 +181,49 @@ func TestAccProviderIndirectUserProjectOverride(t *testing.T) { }) } +func TestAccProviderCredentialsEmptyString(t *testing.T) { + // Test is not parallel because ENVs are set. + // Need to skip VCR as this test downloads providers from the Terraform Registry + acctest.SkipIfVcr(t) + + creds := envvar.GetTestCredsFromEnv() + project := envvar.GetTestProjectFromEnv() + t.Setenv("GOOGLE_CREDENTIALS", creds) + t.Setenv("GOOGLE_PROJECT", project) + + pid := "tf-test-" + acctest.RandString(t, 10) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + // No TestDestroy since that's not really the point of this test + Steps: []resource.TestStep{ + { + Config: testAccProviderCredentials_actWithCredsFromEnv(pid), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + }, + { + // Assert that errors are expected with credentials when + // - GOOGLE_CREDENTIALS is set + // - provider block has credentials = "" + // - TPG v4.60.2 is used + Config: testAccProviderCredentials_actWithCredsFromEnv_emptyString(pid), + ExternalProviders: map[string]resource.ExternalProvider{ + "google": { + VersionConstraint: "4.60.2", + Source: "hashicorp/google", + }, + }, + ExpectError: regexp.MustCompile(`unexpected end of JSON input`), + }, + { + // Errors are not expected when using the latest 4.x.x version of the provider + Config: testAccProviderCredentials_actWithCredsFromEnv_emptyString(pid), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + }, + }, + }) +} + func testAccProviderBasePath_setBasePath(endpoint, name string) string { return fmt.Sprintf(` provider "google" { @@ -321,4 +364,30 @@ func testAccCheckComputeAddressDestroyProducer(t *testing.T) func(s *terraform.S return nil } -} \ No newline at end of file +} + +func testAccProviderCredentials_actWithCredsFromEnv(name string) string { + return fmt.Sprintf(` +provider "google" { + alias = "testing_credentials" + +} + +resource "google_compute_address" "default" { + provider = google.testing_credentials + name = "%s" +}`, name) +} + +func testAccProviderCredentials_actWithCredsFromEnv_emptyString(name string) string { + return fmt.Sprintf(` +provider "google" { + alias = "testing_credentials" + credentials = "" +} + +resource "google_compute_address" "default" { + provider = google.testing_credentials + name = "%s" +}`, name) +} From b1a59e3eee34185e299a78d8cd0e2b41c9d016f8 Mon Sep 17 00:00:00 2001 From: Ben Partridge <134976887+FiskilBen@users.noreply.github.com> Date: Fri, 15 Sep 2023 04:00:59 +1000 Subject: [PATCH 071/476] Adds server TLS policy property to target HTTPS proxy resource (#8857) --- mmv1/products/compute/TargetHttpsProxy.yaml | 26 ++++++ .../examples/target_https_proxy_mtls.tf.erb | 93 +++++++++++++++++++ .../compute/test-fixtures/ca_cert.pem | 19 ++++ 3 files changed, 138 insertions(+) create mode 100644 mmv1/templates/terraform/examples/target_https_proxy_mtls.tf.erb create mode 100644 mmv1/third_party/terraform/services/compute/test-fixtures/ca_cert.pem diff --git a/mmv1/products/compute/TargetHttpsProxy.yaml b/mmv1/products/compute/TargetHttpsProxy.yaml index aa255fe48128..5f93a0cb2d50 100644 --- a/mmv1/products/compute/TargetHttpsProxy.yaml +++ b/mmv1/products/compute/TargetHttpsProxy.yaml @@ -62,6 +62,18 @@ examples: url_map_name: 'url-map' backend_service_name: 'backend-service' http_health_check_name: 'http-health-check' + - !ruby/object:Provider::Terraform::Examples + name: 'target_https_proxy_mtls' + primary_resource_id: 'default' + min_version: 'beta' + vars: + target_https_proxy_name: 'test-mtls-proxy' + ssl_certificate_name: 'my-certificate' + url_map_name: 'url-map' + backend_service_name: 'backend-service' + http_health_check_name: 'http-health-check' + server_tls_policy_name: 'my-tls-policy' + trust_config_name: 'my-trust-config' properties: - !ruby/object:Api::Type::Time name: 'creationTimestamp' @@ -161,3 +173,17 @@ properties: external HTTP(S) load balancer, the minimum allowed value is 5 seconds and the maximum allowed value is 1200 seconds. For Global external HTTP(S) load balancer (classic), this option is not available publicly. + - !ruby/object:Api::Type::ResourceRef + name: 'serverTlsPolicy' + resource: 'SslPolicy' + imports: 'selfLink' + description: | + A URL referring to a networksecurity.ServerTlsPolicy + resource that describes how the proxy should authenticate inbound + traffic. serverTlsPolicy only applies to a global TargetHttpsProxy + attached to globalForwardingRules with the loadBalancingScheme + set to INTERNAL_SELF_MANAGED or EXTERNAL or EXTERNAL_MANAGED. + For details which ServerTlsPolicy resources are accepted with + INTERNAL_SELF_MANAGED and which with EXTERNAL, EXTERNAL_MANAGED + loadBalancingScheme consult ServerTlsPolicy documentation. + If left blank, communications are not encrypted. diff --git a/mmv1/templates/terraform/examples/target_https_proxy_mtls.tf.erb b/mmv1/templates/terraform/examples/target_https_proxy_mtls.tf.erb new file mode 100644 index 000000000000..c77f12732a4d --- /dev/null +++ b/mmv1/templates/terraform/examples/target_https_proxy_mtls.tf.erb @@ -0,0 +1,93 @@ +# [START cloudloadbalancing_target_https_proxy_mtls] +data "google_project" "project" { + provider = google-beta +} + +resource "google_compute_target_https_proxy" "<%= ctx[:primary_resource_id] %>" { + provider = google-beta + name = "<%= ctx[:vars]['target_https_proxy_name'] %>" + url_map = google_compute_url_map.default.id + ssl_certificates = [google_compute_ssl_certificate.default.id] + server_tls_policy = google_network_security_server_tls_policy.default.id +} + +resource "google_certificate_manager_trust_config" "default" { + provider = google-beta + name = "<%= ctx[:vars]["trust_config_name"] %>" + description = "sample description for the trust config" + location = "global" + + trust_stores { + trust_anchors { + pem_certificate = file("test-fixtures/ca_cert.pem") + } + intermediate_cas { + pem_certificate = file("test-fixtures/ca_cert.pem") + } + } + + labels = { + foo = "bar" + } +} + +resource "google_network_security_server_tls_policy" "default" { + provider = google-beta + name = "<%= ctx[:vars]['server_tls_policy_name'] %>" + description = "my description" + location = "global" + allow_open = "false" + mtls_policy { + client_validation_mode = "ALLOW_INVALID_OR_MISSING_CLIENT_CERT" + client_validation_trust_config = "projects/${data.google_project.project.number}/locations/global/trustConfigs/${google_certificate_manager_trust_config.default.name}" + } +} + +resource "google_compute_ssl_certificate" "default" { + provider = google-beta + name = "<%= ctx[:vars]['ssl_certificate_name'] %>" + private_key = file("path/to/private.key") + certificate = file("path/to/certificate.crt") +} + +resource "google_compute_url_map" "default" { + provider = google-beta + name = "<%= ctx[:vars]['url_map_name'] %>" + description = "a description" + + default_service = google_compute_backend_service.default.id + + host_rule { + hosts = ["mysite.com"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = google_compute_backend_service.default.id + + path_rule { + paths = ["/*"] + service = google_compute_backend_service.default.id + } + } +} + +resource "google_compute_backend_service" "default" { + provider = google-beta + name = "<%= ctx[:vars]['backend_service_name'] %>" + port_name = "http" + protocol = "HTTP" + timeout_sec = 10 + + health_checks = [google_compute_http_health_check.default.id] +} + +resource "google_compute_http_health_check" "default" { + provider = google-beta + name = "<%= ctx[:vars]['http_health_check_name'] %>" + request_path = "/" + check_interval_sec = 1 + timeout_sec = 1 +} +# [END cloudloadbalancing_target_https_proxy_mtls] diff --git a/mmv1/third_party/terraform/services/compute/test-fixtures/ca_cert.pem b/mmv1/third_party/terraform/services/compute/test-fixtures/ca_cert.pem new file mode 100644 index 000000000000..ac1e36438259 --- /dev/null +++ b/mmv1/third_party/terraform/services/compute/test-fixtures/ca_cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAfegAwIBAgIUDOiCLH9QNMMYnjPZVf4VwO9blsEwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wIBcNMjIwODI0MDg0MDUxWhgPMzAy +MTEyMjUwODQwNTFaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOT925GG4lKV9HvAHsbecMhGPAqjhVRC26iZ +UJC8oSWOu95lWJSX5ZhbiF6Nz192wDGV/VAh3Lxj8RYtcn75eDxQKTcKouDld+To +CGIStPFWbR6rbysLuZqFVEXVOTvp2QIegInfrvnGC4j7Qpic7zrFB9HzJx+0HpeE +yO4gkdzJfEK/gMmolUgJrKX59o+0+Rj+Jq3EtcQxL1fVBVJSx0NvpoR1eYpnHMr/ +rJKZkUUZ2xE86hrtpiP6OEYQTi00rmf4GnZF5QfGGD0xuoQXtR7Tu+XhKibXIhxc +D4RzPLX1QS040PXvmMPLDb4YlUQ6V3Rs42JDvkkDwIMXZvn8awIDAQABo1MwUTAd +BgNVHQ4EFgQURuo1CCZZAUv7xi02f2nC5tRbf18wHwYDVR0jBBgwFoAURuo1CCZZ +AUv7xi02f2nC5tRbf18wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AQEAqx3tDxurnYr9EUPhF5/LlDPYM+VI7EgrKdRnuIqUlZI0tm3vOGME0te6dBTC +YLNaHLW3m/4Tm4M2eg0Kpz6CxJfn3109G31dCi0xwzSDHf5TPUWvqIVhq5WRgMIf +n8KYBlQSmqdJBRztUIQH/UPFnSbxymlS4s5qwDgTH5ag9EEBcnWsQ2LZjKi0eqve +MaqAvvB+j8RGZzYY4re94bSJI42zIZ6nMWPtXwRuDc30xl/u+E0jWIgWbPwSd6Km +3wnJnGiU2ezPGq3zEU+Rc39VVIFKQpciNeYuF3neHPJvYOf58qW2Z8s0VH0MR1x3 +3DoO/e30FIr9j+PRD+s5BPKF2A== +-----END CERTIFICATE----- From 54604c0369510acb163361dffabae5e5df2752a8 Mon Sep 17 00:00:00 2001 From: "Bob \"Wombat\" Hogg" Date: Thu, 14 Sep 2023 14:53:01 -0400 Subject: [PATCH 072/476] docs(firestore_database): Fix typo in google_firestore_database locationId (#8957) --- mmv1/products/firestore/Database.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/products/firestore/Database.yaml b/mmv1/products/firestore/Database.yaml index dad854e2c647..1b4bc7c8978f 100644 --- a/mmv1/products/firestore/Database.yaml +++ b/mmv1/products/firestore/Database.yaml @@ -117,7 +117,7 @@ properties: name: locationId required: true description: | - The location of the database. Available databases are listed at + The location of the database. Available locations are listed at https://cloud.google.com/firestore/docs/locations. immutable: true - !ruby/object:Api::Type::Enum From 210d29433c14d2b46ec8a432ee2e2ca173642599 Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Thu, 14 Sep 2023 13:52:57 -0700 Subject: [PATCH 073/476] Add new service to infra file (#8959) --- .ci/infra/terraform/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/infra/terraform/main.tf b/.ci/infra/terraform/main.tf index fa6d3a584595..6e566aad9fcd 100644 --- a/.ci/infra/terraform/main.tf +++ b/.ci/infra/terraform/main.tf @@ -213,6 +213,7 @@ module "project-services" { "dataform.googleapis.com", "datafusion.googleapis.com", "datamigration.googleapis.com", + "datapipelines.googleapis.com", "dataplex.googleapis.com", "dataproc.googleapis.com", "datastore.googleapis.com", From 30eccf278be89d039a5905295288a0752508c179 Mon Sep 17 00:00:00 2001 From: abheda-crest <105624942+abheda-crest@users.noreply.github.com> Date: Fri, 15 Sep 2023 02:38:52 +0530 Subject: [PATCH 074/476] Added is_secret_data_base64 field to (#8873) google_secret_manager_secret_version --- .../products/secretmanager/SecretVersion.yaml | 17 ++++++++++++- .../secret_version_secret_data.go.erb | 24 ++++++++++++++++++ .../secret_version_access.go.erb | 12 ++++++--- ...sion_with_base64_string_secret_data.tf.erb | 18 +++++++++++++ ...ecret_version_is_secret_data_base64.go.erb | 21 +++++++++++++++ ...ecret_version_is_secret_data_base64.go.erb | 20 +++++++++++++++ .../test-fixtures/binary-file.pfx | Bin 0 -> 2621 bytes 7 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 mmv1/templates/terraform/custom_expand/secret_version_secret_data.go.erb create mode 100644 mmv1/templates/terraform/examples/secret_version_with_base64_string_secret_data.tf.erb create mode 100644 mmv1/templates/terraform/extra_schema_entry/secret_version_is_secret_data_base64.go.erb create mode 100644 mmv1/templates/terraform/pre_read/secret_version_is_secret_data_base64.go.erb create mode 100644 mmv1/third_party/terraform/services/secretmanager/test-fixtures/binary-file.pfx diff --git a/mmv1/products/secretmanager/SecretVersion.yaml b/mmv1/products/secretmanager/SecretVersion.yaml index c7218c98887b..7170c3e426bc 100644 --- a/mmv1/products/secretmanager/SecretVersion.yaml +++ b/mmv1/products/secretmanager/SecretVersion.yaml @@ -45,6 +45,16 @@ examples: data: 'secret-data' ignore_read_extra: - 'deletion_policy' + - !ruby/object:Provider::Terraform::Examples + name: 'secret_version_with_base64_string_secret_data' + primary_resource_id: 'secret-version-base64' + vars: + secret_id: 'secret-version' + data: 'secret-data.pfx' + test_vars_overrides: + data: '"./test-fixtures/binary-file.pfx"' + ignore_read_extra: + - 'is_secret_data_base64' import_format: ['projects/{{%project}}/secrets/{{%secret_id}}/versions/{{%version}}'] custom_code: !ruby/object:Provider::Terraform::CustomCode @@ -54,6 +64,11 @@ custom_code: !ruby/object:Provider::Terraform::CustomCode resource_definition: templates/terraform/resource_definition/secret_version.go.erb decoder: templates/terraform/decoders/treat_destroyed_state_as_gone.erb pre_delete: templates/terraform/pre_delete/secret_version_deletion_policy.go.erb + pre_read: templates/terraform/pre_read/secret_version_is_secret_data_base64.go.erb + extra_schema_entry: templates/terraform/extra_schema_entry/secret_version_is_secret_data_base64.go.erb +docs: !ruby/object:Provider::Terraform::Docs + optional_properties: | + * `is_secret_data_base64` - (Optional) If set to 'true', the secret data is expected to be base64-encoded string and would be sent as is. virtual_fields: - !ruby/object:Api::Type::Enum name: 'deletion_policy' @@ -123,4 +138,4 @@ properties: required: true description: The secret data. Must be no larger than 64KiB. sensitive: true - custom_expand: templates/terraform/custom_expand/base64.go.erb + custom_expand: templates/terraform/custom_expand/secret_version_secret_data.go.erb diff --git a/mmv1/templates/terraform/custom_expand/secret_version_secret_data.go.erb b/mmv1/templates/terraform/custom_expand/secret_version_secret_data.go.erb new file mode 100644 index 000000000000..1ac3a0450046 --- /dev/null +++ b/mmv1/templates/terraform/custom_expand/secret_version_secret_data.go.erb @@ -0,0 +1,24 @@ +<%- # the license inside this block applies to this file + # 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. +-%> +func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + if v == nil { + return nil, nil + } + + if d.Get("is_secret_data_base64").(bool) { + return v, nil + } + return base64.StdEncoding.EncodeToString([]byte(v.(string))), nil +} diff --git a/mmv1/templates/terraform/custom_flatten/secret_version_access.go.erb b/mmv1/templates/terraform/custom_flatten/secret_version_access.go.erb index 7b4320b47dac..fbfc706d5242 100644 --- a/mmv1/templates/terraform/custom_flatten/secret_version_access.go.erb +++ b/mmv1/templates/terraform/custom_flatten/secret_version_access.go.erb @@ -45,10 +45,14 @@ func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d return err } - data, err := base64.StdEncoding.DecodeString(accessRes["payload"].(map[string]interface{})["data"].(string)) - if err != nil { - return err + if d.Get("is_secret_data_base64").(bool) { + transformed["secret_data"] = accessRes["payload"].(map[string]interface{})["data"].(string) + } else { + data, err := base64.StdEncoding.DecodeString(accessRes["payload"].(map[string]interface{})["data"].(string)) + if err != nil { + return err + } + transformed["secret_data"] = string(data) } - transformed["secret_data"] = string(data) return []interface{}{transformed} } diff --git a/mmv1/templates/terraform/examples/secret_version_with_base64_string_secret_data.tf.erb b/mmv1/templates/terraform/examples/secret_version_with_base64_string_secret_data.tf.erb new file mode 100644 index 000000000000..c9fd886c37a5 --- /dev/null +++ b/mmv1/templates/terraform/examples/secret_version_with_base64_string_secret_data.tf.erb @@ -0,0 +1,18 @@ +resource "google_secret_manager_secret" "secret-basic" { + secret_id = "<%= ctx[:vars]['secret_id'] %>" + + replication { + user_managed { + replicas { + location = "us-central1" + } + } + } +} + +resource "google_secret_manager_secret_version" "<%= ctx[:primary_resource_id] %>" { + secret = google_secret_manager_secret.secret-basic.id + + is_secret_data_base64 = true + secret_data = filebase64("<%= ctx[:vars]['data'] %>") +} diff --git a/mmv1/templates/terraform/extra_schema_entry/secret_version_is_secret_data_base64.go.erb b/mmv1/templates/terraform/extra_schema_entry/secret_version_is_secret_data_base64.go.erb new file mode 100644 index 000000000000..4a7326ae8a22 --- /dev/null +++ b/mmv1/templates/terraform/extra_schema_entry/secret_version_is_secret_data_base64.go.erb @@ -0,0 +1,21 @@ +<%# The license inside this block applies to this file. + # 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. +-%> +"is_secret_data_base64": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: false, + Description: `If set to 'true', the secret data is expected to be base64-encoded string and would be sent as is.`, +}, diff --git a/mmv1/templates/terraform/pre_read/secret_version_is_secret_data_base64.go.erb b/mmv1/templates/terraform/pre_read/secret_version_is_secret_data_base64.go.erb new file mode 100644 index 000000000000..e51b366178d9 --- /dev/null +++ b/mmv1/templates/terraform/pre_read/secret_version_is_secret_data_base64.go.erb @@ -0,0 +1,20 @@ +<%# The license inside this block applies to this file. + # 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. +-%> +// Explicitly set the field to default value if unset +if _, ok := d.GetOkExists("is_secret_data_base64"); !ok { + if err := d.Set("is_secret_data_base64", false); err != nil { + return fmt.Errorf("Error setting is_secret_data_base64: %s", err) + } +} diff --git a/mmv1/third_party/terraform/services/secretmanager/test-fixtures/binary-file.pfx b/mmv1/third_party/terraform/services/secretmanager/test-fixtures/binary-file.pfx new file mode 100644 index 0000000000000000000000000000000000000000..5c1caa0337e6aa1eda8ebbf69097707eceaece83 GIT binary patch literal 2621 zcmY+^c{CJ^8V2y0F*LSpV>GgjwP<`}H%#_@CwmMbWRI~EMo6}lEZMg~^d&oy^^*@- z%93Unib097C0nk}x%Yne{_&pooaZ^``SXXuGoV308Wf)XjE-JBQ7`d;8F&F$f~Ti~ z@$?(#@fr#bF8-&YE5U;wokyu4AmIEZ{L=tYJai2IUSI;!p)P_UxzD14Ok#e@fj|&I zEFNr&{=}$sD|W&Vz;k1PbGw~XQvAk2!Ru0)*xPC|6ZDu1Asy%>@b)H!Zz`HW$A|EN z1TpYgv;=Rz`V}MmGBrfj)#hPDyOU|?)?7BpJ(^wNg5^OnS!NNsGv1=^n$B>@>o(39DTxzbFG^OO2Ko`OEE?ctj?wlI>jB)nzI2w|4(=A zidz*Hp^@TqvbW1$RUlZPkAB3H>|Lh;_z5n@jv*#NQjT6&-eepMW1&VQLDsR8(OUE! zb%?;zhtGPFblQaZtxR*EpDoGM_e+1s)ZxXd=y0$0=5|sKk-NnS+BP@m0Q~1CwyBN;KmI1a+skak*mj-D4*hLM_7m0=jU)%l?ldb^3xEdr)pr zMuwByD)>H5>&hX#n5MxBv>!zyn*n6s*h_`A7OqJvbzxp!=DeJ`LRM{L{5!?y+pLAi zou_``3OqSLN!OpHoh+C38hx*ZUl&BlTC*tfC4jI}l+#^FDF^YRhs=9bO)9LMCXe1k z`Xvs3F&Mlz={2D%LNsAd=L-DAo2Q_V74~%76vkNU$7Z~pt#X1TK_n!H)y*SXB*Bg*36lSkCA8S~F+o`|NR2!= zSeF$j`sGPpu$tX)_a>poBVR+{if2osh-~i2cs9BfiD6U!P$PDSgOXuFx@a?CW23FH z(JFb^S4Fi*2-pom(kpw^t8BSxZ!Qh)#~ANu>#0kW_DdCtHaKXi?U<4hJ;qZCs0MOY zV!Dm!HitMigOir30o)ZbUc{ZO11O*hey7VcxehswZTxui@Ie#CzN?e`*X_y4u@jE2 z4xZ=hmEBfW%Knd^m~lsyI$#ZcNyWftDMfMSk4zHJh^OyV#1jkw-lgdV&Lm?Lo>u*TAS%JrN`vvVlIOAb`H9jo{)Z(7An4q$&2zZE z{-0JfzqLBd@5V^HskQs96&Md5DqY~_8`Cso{RSN8RGR5vS)XM_sQ2+q!bQV3!BtjS z5w?bVIL$fqn8Q(6HHw|lVpOM4JtFM!l>wc~MT^Lv@K{}2q!o#|ahMI8aA(npaLu2& zM_;3~S&-e5Q0qAZz6>I6S_GJL2?>Z`(}Ds=Yhu%*V^&JY=qa#x?VpRP_2v4DTmAT_ z?E!E#vX1KBxMKicQ--=kShv)d@j^OxDNltopCqWQ1#RKtJ8I;O@UU%&sZSnH8P&zu0<%{Rz9 zEs-WZS($%3Qzb^OsN#-|<$=dH^FxR>qxVxLy`YBJJ>0{?kph#khJd5iG?R|&LcV@o zmDnTIRoc`+!TTdceZauiGnq2O)Da#GPgcmY#?$4fyoeVA>cq(AYg%*K%?bwsw<%Jc z=<6~KCqE3mm;j>lx-A2lvfebjX#Tr5|243d9_vIN6+{imy?B>F^HbOMM{72NEqfR-QDdH@utu^-Adn#Ey7bhb==anHIh~F=x zowM){fbrg2dJn4kHDxO7OvkRl$u^h>IL(HO_=OSL>%7A(K{b3mJi!%9LUExFzbQU( zVet;Y)PKbleECt7;0u#B#NNa+V(w#TmWDqy&olSyJvc*7rwOh8WcZAjuaKONyAHWW zNPQ*sTvO__&^7+CnhU{>na?Nq`QLuKZAU`7GXg}eQQd_#^1wuVH*tiO?N*hxQInTY z!`11ol$$vusN_%kgI@q_=YZ>?SyM>-o5{0EyNcZTmiBqE+@}8MP!`3$CL66KtCSpi4x2^l*cY7wSmFg4yuaZ^THYWvu?_70l>(u*# zB3=2!dXO^*``)XVq1e9<-&Fg)kMw>#J@4b7pm9ctWa%GclLRK@H)Ph6B_-U>q(o3c z|J9M6Qwj!#a&QE`UWI%N46;(O{4h0RM(_pTP*Nxaik^;E;vx-*n-&0u+TUBe(DWYJ d)ndo^Av9keh%Tbp1VfPX8hku>i<;j`{tGPP!XN+u literal 0 HcmV?d00001 From 676f2e40e2cac63a5b3b6922890c47258dae38de Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Thu, 14 Sep 2023 15:24:08 -0700 Subject: [PATCH 075/476] Bump EdgeCacheOrigin timeout + add reference docs (#8960) --- mmv1/products/networkservices/EdgeCacheOrigin.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mmv1/products/networkservices/EdgeCacheOrigin.yaml b/mmv1/products/networkservices/EdgeCacheOrigin.yaml index ddd14fe88e2c..3f2205323602 100644 --- a/mmv1/products/networkservices/EdgeCacheOrigin.yaml +++ b/mmv1/products/networkservices/EdgeCacheOrigin.yaml @@ -20,15 +20,17 @@ update_verb: :PATCH update_mask: true description: | EdgeCacheOrigin represents a HTTP-reachable backend for an EdgeCacheService. +references: !ruby/object:Api::Resource::ReferenceLinks + api: 'https://cloud.google.com/media-cdn/docs/reference/rest/v1/projects.locations.edgeCacheOrigins' async: !ruby/object:Api::OpAsync operation: !ruby/object:Api::OpAsync::Operation path: 'name' base_url: '{{op_id}}' wait_ms: 1000 timeouts: !ruby/object:Api::Timeouts - insert_minutes: 60 - update_minutes: 60 - delete_minutes: 60 + insert_minutes: 120 + update_minutes: 120 + delete_minutes: 120 result: !ruby/object:Api::OpAsync::Result path: 'response' status: !ruby/object:Api::OpAsync::Status From 3e823ec7d82171f640d902b6722c64eeec9c0dce Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Thu, 14 Sep 2023 17:40:34 -0500 Subject: [PATCH 076/476] Fix acctest import for tpu v2 (#8958) --- .../terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb b/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb index 6fbb45c2f5b3..0365f1e35688 100644 --- a/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb +++ b/mmv1/third_party/terraform/services/tpuv2/resource_tpu_v2_vm_test.go.erb @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" + "github.com/hashicorp/terraform-provider-google/google/acctest" ) func TestAccTpuV2Vm_update(t *testing.T) { From 27428b5e7de0df1b753f5f7a3191b4b7286f0cea Mon Sep 17 00:00:00 2001 From: ron-gal <125445217+ron-gal@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:43:09 -0400 Subject: [PATCH 077/476] Added read timeout to bigtable instance (#8948) --- .../services/bigtable/resource_bigtable_instance.go | 7 +++++-- .../website/docs/r/bigtable_instance.html.markdown | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go index ecb97c65aa52..b3c867fa8df6 100644 --- a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go +++ b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance.go @@ -31,6 +31,7 @@ func ResourceBigtableInstance() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(60 * time.Minute), Update: schema.DefaultTimeout(60 * time.Minute), + Read: schema.DefaultTimeout(60 * time.Minute), }, CustomizeDiff: customdiff.All( @@ -255,7 +256,9 @@ func resourceBigtableInstanceRead(d *schema.ResourceData, meta interface{}) erro instanceName := d.Get("name").(string) - instance, err := c.InstanceInfo(ctx, instanceName) + ctxWithTimeout, cancel := context.WithTimeout(ctx, d.Timeout(schema.TimeoutRead)) + defer cancel() + instance, err := c.InstanceInfo(ctxWithTimeout, instanceName) if err != nil { if tpgresource.IsNotFoundGrpcError(err) { log.Printf("[WARN] Removing %s because it's gone", instanceName) @@ -269,7 +272,7 @@ func resourceBigtableInstanceRead(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error setting project: %s", err) } - clusters, err := c.Clusters(ctx, instance.Name) + clusters, err := c.Clusters(ctxWithTimeout, instance.Name) if err != nil { partiallyUnavailableErr, ok := err.(bigtable.ErrPartiallyUnavailable) diff --git a/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown b/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown index 6536a90b7800..1dbe10bfed87 100644 --- a/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown @@ -150,6 +150,7 @@ This resource provides the following - `create` - Default is 60 minutes. - `update` - Default is 60 minutes. +- `read` - Default is 60 minutes. Adding clusters to existing instances can take a long time. Consider setting a higher value to timeouts if you plan on doing that. From c1d559b6d428ab2be267850c5a7d4632f6f0fbf4 Mon Sep 17 00:00:00 2001 From: ron-gal <125445217+ron-gal@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:03:40 -0400 Subject: [PATCH 078/476] Add test for unavailable zones logic (#8938) * Add test for unavailable zones logic * Add test for unavailable zones logic * Add test for unavailable zones logic * Add test for unavailable zones logic * Add test for unavailable zones logic --- ...esource_bigtable_instance_internal_test.go | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance_internal_test.go diff --git a/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance_internal_test.go b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance_internal_test.go new file mode 100644 index 000000000000..de25b1b51ed2 --- /dev/null +++ b/mmv1/third_party/terraform/services/bigtable/resource_bigtable_instance_internal_test.go @@ -0,0 +1,50 @@ +package bigtable + +import ( + "reflect" + "testing" +) + +func TestGetUnavailableClusterZones(t *testing.T) { + cases := map[string]struct { + clusterZones []string + unavailableZones []string + want []string + }{ + "not unavailalbe": { + clusterZones: []string{"us-central1", "eu-west1"}, + unavailableZones: []string{"us-central2", "eu-west2"}, + want: nil, + }, + "unavailable one to one": { + clusterZones: []string{"us-central2"}, + unavailableZones: []string{"us-central2"}, + want: []string{"us-central2"}, + }, + "unavailable one to many": { + clusterZones: []string{"us-central2"}, + unavailableZones: []string{"us-central2", "us-central1"}, + want: []string{"us-central2"}, + }, + "unavailable many to one": { + clusterZones: []string{"us-central2", "us-central1"}, + unavailableZones: []string{"us-central2"}, + want: []string{"us-central2"}, + }, + "unavailable many to many": { + clusterZones: []string{"us-central2", "us-central1"}, + unavailableZones: []string{"us-central2", "us-central1"}, + want: []string{"us-central2", "us-central1"}, + }, + } + + for tn, tc := range cases { + var clusters []interface{} + for _, zone := range tc.clusterZones { + clusters = append(clusters, map[string]interface{}{"zone": zone}) + } + if got := getUnavailableClusterZones(clusters, tc.unavailableZones); !reflect.DeepEqual(got, tc.want) { + t.Errorf("bad: %s, got %q, want %q", tn, got, tc.want) + } + } +} From b02d015b8ac29e144fac7da03f2eb510263c9d74 Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Thu, 14 Sep 2023 17:13:46 -0700 Subject: [PATCH 079/476] Add storageinsights.googleapis.com to infra file (#8961) --- .ci/infra/terraform/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/infra/terraform/main.tf b/.ci/infra/terraform/main.tf index 6e566aad9fcd..250738ae5808 100644 --- a/.ci/infra/terraform/main.tf +++ b/.ci/infra/terraform/main.tf @@ -301,6 +301,7 @@ module "project-services" { "storage-api.googleapis.com", "storage-component.googleapis.com", "storage.googleapis.com", + "storageinsights.googleapis.com", "storagetransfer.googleapis.com", "test-file.sandbox.googleapis.com", "testing.googleapis.com", From eb0bf5c68e38709180943ff7993c585be0a3aded Mon Sep 17 00:00:00 2001 From: Neha Vellanki <35039892+neha-vellanki12@users.noreply.github.com> Date: Thu, 14 Sep 2023 20:28:44 -0700 Subject: [PATCH 080/476] adding RestorePlan to Backup for GKE (#8803) * adding RestorePlan to Backup for GKE * fixed spacing issue * fixed more spacing issue * adding newline end of file * fixed trailing spaces * fixed test file names * added test gaps * adding description adn labels * fixed tests * fixed protected application name length * fixed protected app test * fix restore all namespaces test names * removed bp prefix from resource names * removed last bp ref --- mmv1/products/gkebackup/RestorePlan.yaml | 455 ++++++++++++++++++ ...p_restoreplan_all_cluster_resources.tf.erb | 39 ++ ...kebackup_restoreplan_all_namespaces.tf.erb | 40 ++ ...p_restoreplan_protected_application.tf.erb | 44 ++ ...backup_restoreplan_rename_namespace.tf.erb | 66 +++ ...ckup_restoreplan_rollback_namespace.tf.erb | 49 ++ ...p_restoreplan_second_transformation.tf.erb | 64 +++ 7 files changed, 757 insertions(+) create mode 100644 mmv1/products/gkebackup/RestorePlan.yaml create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb diff --git a/mmv1/products/gkebackup/RestorePlan.yaml b/mmv1/products/gkebackup/RestorePlan.yaml new file mode 100644 index 000000000000..b457a450fcb2 --- /dev/null +++ b/mmv1/products/gkebackup/RestorePlan.yaml @@ -0,0 +1,455 @@ +# 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: 'RestorePlan' +base_url: 'projects/{{project}}/locations/{{location}}/restorePlans' +create_url: projects/{{project}}/locations/{{location}}/restorePlans?restorePlanId={{name}} +update_verb: :PATCH +update_mask: true +description: | + Represents a Restore Plan instance. +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Official Documentation': 'https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke' + api: 'https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/projects.locations.restorePlans' +iam_policy: !ruby/object:Api::Resource::IamPolicy + method_name_separator: ':' + parent_resource_attribute: 'name' + base_url: projects/{{project}}/locations/{{location}}/restorePlans/{{name}} + import_format: + [ + 'projects/{{project}}/locations/{{location}}/restorePlans/{{name}}', + '{{name}}', + ] +timeouts: !ruby/object:Api::Timeouts +autogen_async: true +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_all_namespaces' + primary_resource_id: 'all_ns' + primary_resource_name: "fmt.Sprintf(\"tf-test-restore-all-ns%s\", + context[\"random_suffix\"\ + ])" + vars: + name: 'restore-all-ns' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_rollback_namespace' + primary_resource_id: 'rollback_ns' + vars: + name: 'rollback-ns' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_protected_application' + primary_resource_id: 'rollback_app' + vars: + name: 'rollback-app' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_all_cluster_resources' + primary_resource_id: 'all_cluster_resources' + vars: + name: 'all-groupkinds' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_rename_namespace' + primary_resource_id: 'rename_ns' + vars: + name: 'rename-ns' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_second_transformation' + primary_resource_id: 'transform_rule' + vars: + name: 'transform-rule' + test_env_vars: + project: :PROJECT_NAME +skip_sweeper: true +parameters: + - !ruby/object:Api::Type::String + name: 'location' + url_param_only: true + required: true + immutable: true + description: | + The region of the Restore Plan. +properties: + - !ruby/object:Api::Type::String + name: name + required: true + immutable: true + description: | + The full name of the BackupPlan Resource. + custom_expand: 'templates/terraform/custom_expand/shortname_to_url.go.erb' + custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb' + - !ruby/object:Api::Type::String + name: uid + output: true + description: | + Server generated, unique identifier of UUID format. + - !ruby/object:Api::Type::String + name: description + description: | + User specified descriptive string for this RestorePlan. + - !ruby/object:Api::Type::KeyValuePairs + name: labels + description: | + Description: A set of custom labels supplied by the user. + A list of key->value pairs. + Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. + - !ruby/object:Api::Type::String + name: 'backupPlan' + required: true + immutable: true + description: | + A reference to the BackupPlan from which Backups may be used + as the source for Restores created via this RestorePlan. + - !ruby/object:Api::Type::String + name: 'cluster' + required: true + immutable: true + description: | + The source cluster from which Restores will be created via this RestorePlan. + - !ruby/object:Api::Type::NestedObject + name: restoreConfig + required: true + description: | + Defines the configuration of Restores created via this RestorePlan. + properties: + - !ruby/object:Api::Type::Boolean + name: allNamespaces + description: | + If True, restore all namespaced resources in the Backup. + Setting this field to False will result in an error. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + - !ruby/object:Api::Type::NestedObject + name: excludedNamespaces + description: | + A list of selected namespaces excluded from restoration. + All namespaces except those in this list will be restored. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + properties: + - !ruby/object:Api::Type::Array + name: namespaces + required: true + description: | + A list of Kubernetes Namespaces. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: selectedNamespaces + description: | + A list of selected namespaces to restore from the Backup. + The listed Namespaces and all resources contained in them will be restored. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + properties: + - !ruby/object:Api::Type::Array + name: namespaces + required: true + description: | + A list of Kubernetes Namespaces. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: selectedApplications + description: | + A list of selected ProtectedApplications to restore. + The listed ProtectedApplications and all the resources + to which they refer will be restored. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + properties: + - !ruby/object:Api::Type::Array + name: namespacedNames + required: true + description: | + A list of namespaced Kubernetes resources. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: namespace + required: true + description: | + The namespace of a Kubernetes Resource. + - !ruby/object:Api::Type::String + name: name + required: true + description: | + The name of a Kubernetes Resource. + - !ruby/object:Api::Type::Boolean + name: noNamespaces + description: | + Do not restore any namespaced resources if set to "True". + Specifying this field to "False" is not allowed. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + - !ruby/object:Api::Type::Enum + name: namespacedResourceRestoreMode + description: | + Defines the behavior for handling the situation where sets of namespaced resources + being restored already exist in the target cluster. + This MUST be set to a value other than `NAMESPACED_RESOURCE_RESTORE_MODE_UNSPECIFIED` + if the `namespacedResourceRestoreScope` is anything other than `noNamespaces`. + See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#namespacedresourcerestoremode + for more information on each mode. + values: + - :DELETE_AND_RESTORE + - :FAIL_ON_CONFLICT + - !ruby/object:Api::Type::Enum + name: volumeDataRestorePolicy + description: | + Specifies the mechanism to be used to restore volume data. + This should be set to a value other than `NAMESPACED_RESOURCE_RESTORE_MODE_UNSPECIFIED` + if the `namespacedResourceRestoreScope` is anything other than `noNamespaces`. + If not specified, it will be treated as `NO_VOLUME_DATA_RESTORATION`. + See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#VolumeDataRestorePolicy + for more information on each policy option. + values: + - :RESTORE_VOLUME_DATA_FROM_BACKUP + - :REUSE_VOLUME_HANDLE_FROM_BACKUP + - :NO_VOLUME_DATA_RESTORATION + - !ruby/object:Api::Type::NestedObject + name: clusterResourceRestoreScope + description: | + Identifies the cluster-scoped resources to restore from the Backup. + properties: + - !ruby/object:Api::Type::Boolean + name: allGroupKinds + description: | + If True, all valid cluster-scoped resources will be restored. + Mutually exclusive to any other field in `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + - !ruby/object:Api::Type::Array + name: excludedGroupKinds + description: | + A list of cluster-scoped resource group kinds to NOT restore from the backup. + If specified, all valid cluster-scoped resources will be restored except + for those specified in the list. + Mutually exclusive to any other field in `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + item_type: !ruby/object:Api::Type::NestedObject + required: true + properties: + - !ruby/object:Api::Type::String + name: resourceGroup + description: | + API Group string of a Kubernetes resource, e.g. + "apiextensions.k8s.io", "storage.k8s.io", etc. + Use empty string for core group. + - !ruby/object:Api::Type::String + name: resourceKind + description: | + Kind of a Kubernetes resource, e.g. + "CustomResourceDefinition", "StorageClass", etc. + - !ruby/object:Api::Type::Array + name: selectedGroupKinds + description: | + A list of cluster-scoped resource group kinds to restore from the backup. + If specified, only the selected resources will be restored. + Mutually exclusive to any other field in the `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + item_type: !ruby/object:Api::Type::NestedObject + required: true + properties: + - !ruby/object:Api::Type::String + name: resourceGroup + description: | + API Group string of a Kubernetes resource, e.g. + "apiextensions.k8s.io", "storage.k8s.io", etc. + Use empty string for core group. + - !ruby/object:Api::Type::String + name: resourceKind + description: | + Kind of a Kubernetes resource, e.g. + "CustomResourceDefinition", "StorageClass", etc. + - !ruby/object:Api::Type::Boolean + name: noGroupKinds + description: | + If True, no cluster-scoped resources will be restored. + Mutually exclusive to any other field in `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + - !ruby/object:Api::Type::Enum + name: clusterResourceConflictPolicy + description: | + Defines the behavior for handling the situation where cluster-scoped resources + being restored already exist in the target cluster. + This MUST be set to a value other than `CLUSTER_RESOURCE_CONFLICT_POLICY_UNSPECIFIED` + if `clusterResourceRestoreScope` is anyting other than `noGroupKinds`. + See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#clusterresourceconflictpolicy + for more information on each policy option. + values: + - :USE_EXISTING_VERSION + - :USE_BACKUP_VERSION + - !ruby/object:Api::Type::Array + name: transformationRules + description: | + A list of transformation rules to be applied against Kubernetes + resources as they are selected for restoration from a Backup. + Rules are executed in order defined - this order matters, + as changes made by a rule may impact the filtering logic of subsequent + rules. An empty list means no transformation will occur. + item_type: !ruby/object:Api::Type::NestedObject + required: true + description: | + A transformation rule to be applied against Kubernetes resources + as they are selected for restoration from a Backup. + A rule contains both filtering logic + (which resources are subject to transform) and transformation logic. + properties: + - !ruby/object:Api::Type::String + name: description + description: | + The description is a user specified string description + of the transformation rule. + - !ruby/object:Api::Type::NestedObject + name: resourceFilter + description: | + This field is used to specify a set of fields that should be used to + determine which resources in backup should be acted upon by the + supplied transformation rule actions, and this will ensure that only + specific resources are affected by transformation rule actions. + properties: + - !ruby/object:Api::Type::Array + name: namespaces + description: | + (Filtering parameter) Any resource subject to transformation must + be contained within one of the listed Kubernetes Namespace in the + Backup. If this field is not provided, no namespace filtering will + be performed (all resources in all Namespaces, including all + cluster-scoped resources, will be candidates for transformation). + To mix cluster-scoped and namespaced resources in the same rule, + use an empty string ("") as one of the target namespaces. + item_type: Api::Type::String + - !ruby/object:Api::Type::Array + name: groupKinds + description: | + (Filtering parameter) Any resource subject to transformation must + belong to one of the listed "types". If this field is not provided, + no type filtering will be performed + (all resources of all types matching previous filtering parameters + will be candidates for transformation). + item_type: !ruby/object:Api::Type::NestedObject + required: true + properties: + - !ruby/object:Api::Type::String + name: resourceGroup + description: | + API Group string of a Kubernetes resource, e.g. + "apiextensions.k8s.io", "storage.k8s.io", etc. + Use empty string for core group. + - !ruby/object:Api::Type::String + name: resourceKind + description: | + Kind of a Kubernetes resource, e.g. + "CustomResourceDefinition", "StorageClass", etc. + - !ruby/object:Api::Type::String + name: jsonPath + description: | + This is a JSONPath expression that matches specific fields of + candidate resources and it operates as a filtering parameter + (resources that are not matched with this expression will not + be candidates for transformation). + - !ruby/object:Api::Type::Array + name: fieldActions + required: true + description: | + A list of transformation rule actions to take against candidate + resources. Actions are executed in order defined - this order + matters, as they could potentially interfere with each other and + the first operation could affect the outcome of the second operation. + item_type: !ruby/object:Api::Type::NestedObject + required: true + description: | + TransformationRuleAction defines a TransformationRule action + based on the JSON Patch RFC (https://www.rfc-editor.org/rfc/rfc6902) + properties: + - !ruby/object:Api::Type::Enum + name: op + required: true + description: | + Specifies the operation to perform. + values: + - :REMOVE + - :MOVE + - :COPY + - :ADD + - :TEST + - :REPLACE + - !ruby/object:Api::Type::String + name: fromPath + description: | + A string containing a JSON Pointer value that references the + location in the target document to move the value from. + - !ruby/object:Api::Type::String + name: path + description: | + A string containing a JSON-Pointer value that references a + location within the target document where the operation is performed. + - !ruby/object:Api::Type::String + name: value + description: | + A string that specifies the desired value in string format + to use for transformation. + - !ruby/object:Api::Type::String + name: state + output: true + description: | + The State of the RestorePlan. + - !ruby/object:Api::Type::String + name: stateReason + output: true + description: | + Detailed description of why RestorePlan is in its current state. diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb new file mode 100644 index 000000000000..4578aba10489 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb @@ -0,0 +1,39 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "all_cluster_resources" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + no_namespaces = true + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + cluster_resource_restore_scope { + all_group_kinds = true + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + } +} diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb new file mode 100644 index 000000000000..94c5d25f55ba --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb @@ -0,0 +1,40 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "all_ns" { + name = "<%= ctx[:vars]['name'] %>" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + all_namespaces = true + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + cluster_resource_restore_scope { + all_group_kinds = true + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + } +} \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb new file mode 100644 index 000000000000..64585c3f89a0 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb @@ -0,0 +1,44 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "rollback_app" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + selected_applications { + namespaced_names { + name = "my-app" + namespace = "my-ns" + } + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" + volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" + cluster_resource_restore_scope { + no_group_kinds = true + } + } +} diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb new file mode 100644 index 000000000000..11179e2afee6 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb @@ -0,0 +1,66 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "rename_ns" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + selected_namespaces { + namespaces = ["ns1"] + } + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" + cluster_resource_restore_scope { + no_group_kinds = true + } + transformation_rules { + description = "rename namespace from ns1 to ns2" + resource_filter { + group_kinds { + resource_kind = "Namespace" + } + json_path = ".metadata[?(@.name == 'ns1')]" + } + field_actions { + op = "REPLACE" + path = "/metadata/name" + value = "ns2" + } + } + transformation_rules { + description = "move all resources from ns1 to ns2" + resource_filter { + namespaces = ["ns1"] + } + field_actions { + op = "REPLACE" + path = "/metadata/namespace" + value = "ns2" + } + } + } +} \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb new file mode 100644 index 000000000000..e2b76bae6d28 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb @@ -0,0 +1,49 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "rollback_ns" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + selected_namespaces { + namespaces = ["my-ns"] + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + cluster_resource_restore_scope { + selected_group_kinds { + resource_group = "apiextension.k8s.io" + resource_kind = "CustomResourceDefinition" + } + selected_group_kinds { + resource_group = "storage.k8s.io" + resource_kind = "StorageClass" + } + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + } +} diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb new file mode 100644 index 000000000000..1392a5997f74 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb @@ -0,0 +1,64 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "transform_rule" { + name = "<%= ctx[:vars]['name'] %>-rp" + description = "copy nginx env variables" + labels = { + "app" = "nginx" + } + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + excluded_namespaces { + namespaces = ["my-ns"] + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + cluster_resource_restore_scope { + excluded_group_kinds { + resource_group = "apiextension.k8s.io" + resource_kind = "CustomResourceDefinition" + } + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + transformation_rules { + description = "Copy environment variables from the nginx container to the install init container." + resource_filter { + group_kinds { + resource_kind = "Pod" + resource_group = "" + } + json_path = ".metadata[?(@.name == 'nginx')]" + } + field_actions { + op = "COPY" + path = "/spec/initContainers/0/env" + from_path = "/spec/containers/0/env" + } + } + } +} From a63b21f5a4b5dc391f905acb9dd8962a451a29be Mon Sep 17 00:00:00 2001 From: abheda-crest <105624942+abheda-crest@users.noreply.github.com> Date: Fri, 15 Sep 2023 21:21:34 +0530 Subject: [PATCH 081/476] Removed the `automatic` field from the `google_secret_manager_secret` resource (#8859) --- mmv1/products/secretmanager/Secret.yaml | 17 +- .../secret_manager_replication.go.erb | 180 ------------------ .../secret_manager_replication.go.erb | 118 ------------ ...resource_secret_manager_secret_test.go.erb | 41 ---- 4 files changed, 2 insertions(+), 354 deletions(-) delete mode 100644 mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb delete mode 100644 mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb diff --git a/mmv1/products/secretmanager/Secret.yaml b/mmv1/products/secretmanager/Secret.yaml index c2e8a0832e77..4d4b921ddca9 100644 --- a/mmv1/products/secretmanager/Secret.yaml +++ b/mmv1/products/secretmanager/Secret.yaml @@ -117,29 +117,17 @@ properties: name: replication required: true immutable: true - custom_expand: templates/terraform/custom_expand/secret_manager_replication.go.erb - custom_flatten: templates/terraform/custom_flatten/secret_manager_replication.go.erb description: | The replication policy of the secret data attached to the Secret. It cannot be changed after the Secret has been created. properties: - - !ruby/object:Api::Type::Boolean - name: automatic - immutable: true - exactly_one_of: - - replication.0.automatic - - replication.0.user_managed - - replication.0.auto - deprecation_message: >- - `automatic` is deprecated and will be removed in a future major release. Use `auto` instead. - description: | - The Secret will automatically be replicated without any restrictions. - !ruby/object:Api::Type::NestedObject name: auto api_name: automatic immutable: true + allow_empty_object: true + send_empty_value: true exactly_one_of: - - replication.0.automatic - replication.0.user_managed - replication.0.auto description: | @@ -161,7 +149,6 @@ properties: name: userManaged immutable: true exactly_one_of: - - replication.0.automatic - replication.0.user_managed - replication.0.auto description: | diff --git a/mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb b/mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb deleted file mode 100644 index af13a17e9002..000000000000 --- a/mmv1/templates/terraform/custom_expand/secret_manager_replication.go.erb +++ /dev/null @@ -1,180 +0,0 @@ -<%# The license inside this block applies to this file. - # 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. --%> -func expandSecretManagerSecretReplication(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{}) - - if _, ok := d.GetOk("replication.0.automatic"); ok{ - transformedAutomatic, err := expandSecretManagerSecretReplicationAutomatic(original["automatic"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedAutomatic); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["automatic"] = transformedAutomatic - } - } - - if _, ok := d.GetOk("replication.0.auto"); ok{ - transformedAuto, err := expandSecretManagerSecretReplicationAuto(original["auto"], d, config) - if err != nil { - return nil, err - } else { - transformed["automatic"] = transformedAuto - } - } - - transformedUserManaged, err := expandSecretManagerSecretReplicationUserManaged(original["user_managed"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedUserManaged); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["userManaged"] = transformedUserManaged - } - - return transformed, nil -} - -func expandSecretManagerSecretReplicationAutomatic(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - if v == nil || !v.(bool) { - return nil, nil - } - - return struct{}{}, nil -} - -func expandSecretManagerSecretReplicationAuto(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - if len(l) == 0 { - return nil, nil - } - - if l[0] == nil { - transformed := make(map[string]interface{}) - return transformed, nil - } - raw := l[0] - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedCustomerManagedEncryption, err := expandSecretManagerSecretReplicationAutoCustomerManagedEncryption(original["customer_managed_encryption"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedCustomerManagedEncryption); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["customerManagedEncryption"] = transformedCustomerManagedEncryption - } - - return transformed, nil -} - -func expandSecretManagerSecretReplicationAutoCustomerManagedEncryption(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{}) - - transformedKmsKeyName, err := expandSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(original["kms_key_name"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedKmsKeyName); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["kmsKeyName"] = transformedKmsKeyName - } - - return transformed, nil -} - -func expandSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecretManagerSecretReplicationUserManaged(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{}) - - transformedReplicas, err := expandSecretManagerSecretReplicationUserManagedReplicas(original["replicas"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedReplicas); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["replicas"] = transformedReplicas - } - - return transformed, nil -} - -func expandSecretManagerSecretReplicationUserManagedReplicas(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - l := v.([]interface{}) - req := make([]interface{}, 0, len(l)) - for _, raw := range l { - if raw == nil { - continue - } - original := raw.(map[string]interface{}) - transformed := make(map[string]interface{}) - - transformedLocation, err := expandSecretManagerSecretReplicationUserManagedReplicasLocation(original["location"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedLocation); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["location"] = transformedLocation - } - - transformedCustomerManagedEncryption, err := expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(original["customer_managed_encryption"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedCustomerManagedEncryption); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["customerManagedEncryption"] = transformedCustomerManagedEncryption - } - - req = append(req, transformed) - } - return req, nil -} - -func expandSecretManagerSecretReplicationUserManagedReplicasLocation(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(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{}) - - transformedKmsKeyName, err := expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(original["kms_key_name"], d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedKmsKeyName); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["kmsKeyName"] = transformedKmsKeyName - } - - return transformed, nil -} - -func expandSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} diff --git a/mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb b/mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb deleted file mode 100644 index 76f56f85396d..000000000000 --- a/mmv1/templates/terraform/custom_flatten/secret_manager_replication.go.erb +++ /dev/null @@ -1,118 +0,0 @@ -<%# The license inside this block applies to this file. - # 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. --%> -func flattenSecretManagerSecretReplication(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{}) - _, ok := d.GetOk("replication.0.automatic") - if ok { - transformed["automatic"] = - flattenSecretManagerSecretReplicationAutomatic(original["automatic"], d, config) - } else { - transformed["auto"] = - flattenSecretManagerSecretReplicationAuto(original["automatic"], d, config) - } - transformed["user_managed"] = - flattenSecretManagerSecretReplicationUserManaged(original["userManaged"], d, config) - return []interface{}{transformed} -} -func flattenSecretManagerSecretReplicationAutomatic(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v != nil -} - -func flattenSecretManagerSecretReplicationAuto(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return nil - } - original := v.(map[string]interface{}) - transformed := make(map[string]interface{}) - transformed["customer_managed_encryption"] = - flattenSecretManagerSecretReplicationAutoCustomerManagedEncryption(original["customerManagedEncryption"], d, config) - return []interface{}{transformed} -} -func flattenSecretManagerSecretReplicationAutoCustomerManagedEncryption(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["kms_key_name"] = - flattenSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(original["kmsKeyName"], d, config) - return []interface{}{transformed} -} -func flattenSecretManagerSecretReplicationAutoCustomerManagedEncryptionKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecretManagerSecretReplicationUserManaged(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["replicas"] = - flattenSecretManagerSecretReplicationUserManagedReplicas(original["replicas"], d, config) - return []interface{}{transformed} -} -func flattenSecretManagerSecretReplicationUserManagedReplicas(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - if v == nil { - return v - } - l := v.([]interface{}) - transformed := make([]interface{}, 0, len(l)) - for _, raw := range l { - original := raw.(map[string]interface{}) - if len(original) < 1 { - // Do not include empty json objects coming back from the api - continue - } - transformed = append(transformed, map[string]interface{}{ - "location": flattenSecretManagerSecretReplicationUserManagedReplicasLocation(original["location"], d, config), - "customer_managed_encryption": flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(original["customerManagedEncryption"], d, config), - }) - } - return transformed -} -func flattenSecretManagerSecretReplicationUserManagedReplicasLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryption(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["kms_key_name"] = - flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(original["kmsKeyName"], d, config) - return []interface{}{transformed} -} -func flattenSecretManagerSecretReplicationUserManagedReplicasCustomerManagedEncryptionKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} diff --git a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb index e5c61c864c25..41802a5c5860 100644 --- a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb +++ b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb @@ -234,15 +234,6 @@ func TestAccSecretManagerSecret_automaticCmekUpdate(t *testing.T) { ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), CheckDestroy: testAccCheckSecretManagerSecretDestroyProducer(t), Steps: []resource.TestStep{ - { - Config: testAccSecretMangerSecret_automaticBasic(context), - }, - { - ResourceName: "google_secret_manager_secret.secret-basic", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"ttl", "replication.0.automatic", "replication.0.auto"}, - }, { Config: testAccSecretMangerSecret_automaticCmekBasic(context), }, @@ -698,38 +689,6 @@ resource "google_secret_manager_secret" "secret-basic" { `, context) } -func testAccSecretMangerSecret_automaticBasic(context map[string]interface{}) string { - return acctest.Nprintf(` -data "google_project" "project" { - project_id = "%{pid}" -} -resource "google_kms_crypto_key_iam_member" "kms-secret-binding-1" { - crypto_key_id = "%{kms_key_name_1}" - role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" - member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" -} -resource "google_kms_crypto_key_iam_member" "kms-secret-binding-2" { - crypto_key_id = "%{kms_key_name_2}" - role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" - member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com" -} -resource "google_secret_manager_secret" "secret-basic" { - secret_id = "tf-test-secret-%{random_suffix}" - - labels = { - label = "my-label" - } - replication { - automatic = true - } - depends_on = [ - google_kms_crypto_key_iam_member.kms-secret-binding-1, - google_kms_crypto_key_iam_member.kms-secret-binding-2, - ] -} -`, context) -} - func testAccSecretMangerSecret_automaticCmekBasic(context map[string]interface{}) string { return acctest.Nprintf(` data "google_project" "project" { From dbd00e381a8de9283a3826ef250ce19bc011b3ab Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Fri, 15 Sep 2023 09:27:18 -0700 Subject: [PATCH 082/476] Apply new annotations model to more resources (#8931) --- mmv1/products/cloudrunv2/Job.yaml | 2 +- .../gkeonprem/BareMetalAdminCluster.yaml | 2 +- mmv1/products/gkeonprem/BareMetalCluster.yaml | 3 +-- .../products/gkeonprem/BareMetalNodePool.yaml | 3 +-- mmv1/products/gkeonprem/VmwareCluster.yaml | 3 +-- mmv1/products/gkeonprem/VmwareNodePool.yaml | 3 +-- mmv1/products/secretmanager/Secret.yaml | 2 +- mmv1/products/workstations/Workstation.yaml | 2 +- .../workstations/WorkstationCluster.yaml | 2 +- .../workstations/WorkstationConfig.yaml | 2 +- ...nprem_bare_metal_admin_cluster_full.tf.erb | 4 +++- .../examples/workstation_config_basic.tf.erb | 4 ++++ .../resource_cloud_run_v2_job_test.go | 4 ++-- ...e_gkeonprem_bare_metal_cluster_test.go.erb | 8 ++++++++ ...gkeonprem_bare_metal_node_pool_test.go.erb | 10 ++++++++-- ...ource_gkeonprem_vmware_cluster_test.go.erb | 10 ++++++++-- ...rce_gkeonprem_vmware_node_pool_test.go.erb | 10 ++++++++-- ...resource_secret_manager_secret_test.go.erb | 6 +++--- ...rkstations_workstation_cluster_test.go.erb | 8 ++++---- ...orkstations_workstation_config_test.go.erb | 6 +++--- .../terraform/tpgresource/labels.go | 14 ++++++++++++++ .../terraform/tpgresource/lables.go | 19 ------------------- 22 files changed, 75 insertions(+), 52 deletions(-) delete mode 100644 mmv1/third_party/terraform/tpgresource/lables.go diff --git a/mmv1/products/cloudrunv2/Job.yaml b/mmv1/products/cloudrunv2/Job.yaml index c31f83dce0f5..d8b928f7962f 100644 --- a/mmv1/products/cloudrunv2/Job.yaml +++ b/mmv1/products/cloudrunv2/Job.yaml @@ -137,7 +137,7 @@ properties: Cloud Run API v2 does not support labels with `run.googleapis.com`, `cloud.googleapis.com`, `serving.knative.dev`, or `autoscaling.knative.dev` namespaces, and they will be rejected. All system labels in v1 now have a corresponding field in v2 Job. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: "annotations" description: |- Unstructured key value map that may be set by external tools to store and arbitrary metadata. They are not queryable and should be preserved when modifying objects. diff --git a/mmv1/products/gkeonprem/BareMetalAdminCluster.yaml b/mmv1/products/gkeonprem/BareMetalAdminCluster.yaml index e14dcc81ce9d..1d873319ed61 100644 --- a/mmv1/products/gkeonprem/BareMetalAdminCluster.yaml +++ b/mmv1/products/gkeonprem/BareMetalAdminCluster.yaml @@ -133,7 +133,7 @@ properties: Allows clients to perform consistent read-modify-writes through optimistic concurrency control. output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: "annotations" description: | Annotations on the Bare Metal Admin Cluster. diff --git a/mmv1/products/gkeonprem/BareMetalCluster.yaml b/mmv1/products/gkeonprem/BareMetalCluster.yaml index 0f4bf81e2bf4..a2648c7ef029 100644 --- a/mmv1/products/gkeonprem/BareMetalCluster.yaml +++ b/mmv1/products/gkeonprem/BareMetalCluster.yaml @@ -85,7 +85,7 @@ properties: required: true description: | A human readable description of this Bare Metal User Cluster. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: "annotations" description: | Annotations on the Bare Metal User Cluster. @@ -96,7 +96,6 @@ properties: Prefix must be a DNS subdomain. Name must be 63 characters or less, begin and end with alphanumerics, with dashes (-), underscores (_), dots (.), and alphanumerics between. - default_from_api: true - !ruby/object:Api::Type::NestedObject name: "networkConfig" description: | diff --git a/mmv1/products/gkeonprem/BareMetalNodePool.yaml b/mmv1/products/gkeonprem/BareMetalNodePool.yaml index 42d8ac17f5d1..8060fafcf655 100644 --- a/mmv1/products/gkeonprem/BareMetalNodePool.yaml +++ b/mmv1/products/gkeonprem/BareMetalNodePool.yaml @@ -74,7 +74,7 @@ properties: name: 'displayName' description: | The display name for the Bare Metal Node Pool. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: 'annotations' description: | Annotations on the Bare Metal Node Pool. @@ -85,7 +85,6 @@ properties: Prefix must be a DNS subdomain. Name must be 63 characters or less, begin and end with alphanumerics, with dashes (-), underscores (_), dots (.), and alphanumerics between. - default_from_api: true - !ruby/object:Api::Type::NestedObject name: 'nodePoolConfig' required: true diff --git a/mmv1/products/gkeonprem/VmwareCluster.yaml b/mmv1/products/gkeonprem/VmwareCluster.yaml index f460b42f42bd..c2ccf1c6b2b3 100644 --- a/mmv1/products/gkeonprem/VmwareCluster.yaml +++ b/mmv1/products/gkeonprem/VmwareCluster.yaml @@ -89,7 +89,7 @@ properties: required: true description: | The Anthos clusters on the VMware version for your user cluster. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: 'annotations' description: | Annotations on the VMware User Cluster. @@ -100,7 +100,6 @@ properties: Prefix must be a DNS subdomain. Name must be 63 characters or less, begin and end with alphanumerics, with dashes (-), underscores (_), dots (.), and alphanumerics between. - default_from_api: true - !ruby/object:Api::Type::NestedObject name: 'controlPlaneNode' description: | diff --git a/mmv1/products/gkeonprem/VmwareNodePool.yaml b/mmv1/products/gkeonprem/VmwareNodePool.yaml index bfaf50cdb0ee..1579c1acff40 100644 --- a/mmv1/products/gkeonprem/VmwareNodePool.yaml +++ b/mmv1/products/gkeonprem/VmwareNodePool.yaml @@ -71,7 +71,7 @@ properties: - !ruby/object:Api::Type::String name: "displayName" description: The display name for the node pool. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: "annotations" description: | Annotations on the node Pool. @@ -82,7 +82,6 @@ properties: Prefix must be a DNS subdomain. Name must be 63 characters or less, begin and end with alphanumerics, with dashes (-), underscores (_), dots (.), and alphanumerics between. - default_from_api: true - !ruby/object:Api::Type::NestedObject name: "nodePoolAutoscaling" description: Node Pool autoscaling config for the node pool. diff --git a/mmv1/products/secretmanager/Secret.yaml b/mmv1/products/secretmanager/Secret.yaml index 4d4b921ddca9..be039109d7b9 100644 --- a/mmv1/products/secretmanager/Secret.yaml +++ b/mmv1/products/secretmanager/Secret.yaml @@ -84,7 +84,7 @@ properties: An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: annotations description: | Custom metadata about the secret. diff --git a/mmv1/products/workstations/Workstation.yaml b/mmv1/products/workstations/Workstation.yaml index 39608a4ba043..8edfa75b85e7 100644 --- a/mmv1/products/workstations/Workstation.yaml +++ b/mmv1/products/workstations/Workstation.yaml @@ -122,7 +122,7 @@ properties: description: 'Client-specified labels that are applied to the resource and that are also propagated to the underlying Compute Engine resources.' - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: 'annotations' description: 'Client-specified annotations. This is distinct from labels.' - !ruby/object:Api::Type::KeyValuePairs diff --git a/mmv1/products/workstations/WorkstationCluster.yaml b/mmv1/products/workstations/WorkstationCluster.yaml index ed0f940c896d..e6013adaddbf 100644 --- a/mmv1/products/workstations/WorkstationCluster.yaml +++ b/mmv1/products/workstations/WorkstationCluster.yaml @@ -118,7 +118,7 @@ properties: Whether this resource is in degraded mode, in which case it may require user action to restore full functionality. Details can be found in the conditions field. output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: "annotations" description: "Client-specified annotations. This is distinct from labels." - !ruby/object:Api::Type::Fingerprint diff --git a/mmv1/products/workstations/WorkstationConfig.yaml b/mmv1/products/workstations/WorkstationConfig.yaml index 4a64f9f44852..aafeee3a5d9a 100644 --- a/mmv1/products/workstations/WorkstationConfig.yaml +++ b/mmv1/products/workstations/WorkstationConfig.yaml @@ -158,7 +158,7 @@ properties: description: 'Client-specified labels that are applied to the resource and that are also propagated to the underlying Compute Engine resources.' - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueAnnotations name: 'annotations' description: 'Client-specified annotations. This is distinct from labels.' - !ruby/object:Api::Type::Fingerprint diff --git a/mmv1/templates/terraform/examples/gkeonprem_bare_metal_admin_cluster_full.tf.erb b/mmv1/templates/terraform/examples/gkeonprem_bare_metal_admin_cluster_full.tf.erb index 58046c4f55cc..327d91fd302d 100644 --- a/mmv1/templates/terraform/examples/gkeonprem_bare_metal_admin_cluster_full.tf.erb +++ b/mmv1/templates/terraform/examples/gkeonprem_bare_metal_admin_cluster_full.tf.erb @@ -4,7 +4,9 @@ resource "google_gkeonprem_bare_metal_admin_cluster" "<%= ctx[:primary_resource_ location = "us-west1" description = "test description" bare_metal_version = "1.13.4" - annotations = {} + annotations = { + env = "test" + } network_config { island_mode_cidr { service_address_cidr_blocks = ["172.26.0.0/16"] diff --git a/mmv1/templates/terraform/examples/workstation_config_basic.tf.erb b/mmv1/templates/terraform/examples/workstation_config_basic.tf.erb index 314df7dd12f2..987413cb6199 100644 --- a/mmv1/templates/terraform/examples/workstation_config_basic.tf.erb +++ b/mmv1/templates/terraform/examples/workstation_config_basic.tf.erb @@ -37,6 +37,10 @@ resource "google_workstations_workstation_config" "<%= ctx[:primary_resource_id] idle_timeout = "600s" running_timeout = "21600s" + annotations = { + label-one = "value-one" + } + host { gce_instance { machine_type = "e2-standard-4" diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go index a874e89e16ff..7620f5b6978b 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go @@ -26,7 +26,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "launch_stage"}, + ImportStateVerifyIgnore: []string{"location", "launch_stage", "annotations"}, }, { Config: testAccCloudRunV2Job_cloudrunv2JobFullUpdate(context), @@ -35,7 +35,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "launch_stage"}, + ImportStateVerifyIgnore: []string{"location", "launch_stage", "annotations"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go.erb b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go.erb index be8905f2f378..9664b054d931 100644 --- a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go.erb +++ b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go.erb @@ -27,6 +27,7 @@ func TestAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBasic(t *testing.T) ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-metallb", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, { Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLb(context), @@ -35,6 +36,7 @@ func TestAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBasic(t *testing.T) ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-metallb", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, }, }) @@ -111,6 +113,9 @@ func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLbStart(context provider = google-beta name = "cluster-metallb%{random_suffix}" location = "us-west1" + annotations = { + env = "test" + } admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" bare_metal_version = "1.12.3" network_config { @@ -187,6 +192,9 @@ func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLb(context map[ provider = google-beta name = "cluster-metallb%{random_suffix}" location = "us-west1" + annotations = { + env = "test-update" + } admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" bare_metal_version = "1.12.3" network_config { diff --git a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go.erb b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go.erb index 2819f8f66a34..866021db160f 100644 --- a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go.erb +++ b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go.erb @@ -27,6 +27,7 @@ func TestAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(t *testing.T) { ResourceName: "google_gkeonprem_bare_metal_node_pool.nodepool", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, { Config: testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(context), @@ -35,6 +36,7 @@ func TestAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(t *testing.T) { ResourceName: "google_gkeonprem_bare_metal_node_pool.nodepool", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, }, }) @@ -121,7 +123,9 @@ func testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdateStart(context map[ name = "tf-test-nodepool-%{random_suffix}" location = "us-west1" bare_metal_cluster = google_gkeonprem_bare_metal_cluster.cluster.name - annotations = {} + annotations = { + env = "test" + } node_pool_config { operating_system = "LINUX" labels = {} @@ -215,7 +219,9 @@ func testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(context map[strin name = "tf-test-nodepool-%{random_suffix}" location = "us-west1" bare_metal_cluster = google_gkeonprem_bare_metal_cluster.cluster.name - annotations = {} + annotations = { + env = "test-update" + } node_pool_config { operating_system = "LINUX" labels = {} diff --git a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go.erb b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go.erb index a2cc7e50f7e9..3771d14f521f 100644 --- a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go.erb +++ b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go.erb @@ -27,6 +27,7 @@ func TestAccGkeonpremVmwareCluster_vmwareClusterUpdateBasic(t *testing.T) { ResourceName: "google_gkeonprem_vmware_cluster.cluster", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, { Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLb(context), @@ -35,6 +36,7 @@ func TestAccGkeonpremVmwareCluster_vmwareClusterUpdateBasic(t *testing.T) { ResourceName: "google_gkeonprem_vmware_cluster.cluster", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, }, }) @@ -117,7 +119,9 @@ func testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLbStart(context map[s admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" description = "test cluster" on_prem_version = "1.13.1-gke.35" - annotations = {} + annotations = { + env = "test" + } network_config { service_address_cidr_blocks = ["10.96.0.0/12"] pod_address_cidr_blocks = ["192.168.0.0/16"] @@ -165,7 +169,9 @@ func testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLb(context map[string admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" description = "test cluster updated" on_prem_version = "1.13.1-gke.36" - annotations = {} + annotations = { + env = "test-update" + } network_config { service_address_cidr_blocks = ["10.96.0.0/16"] pod_address_cidr_blocks = ["192.168.0.0/20"] diff --git a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go.erb b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go.erb index 4be86f65a2c1..8589b95ba4e8 100644 --- a/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go.erb +++ b/mmv1/third_party/terraform/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go.erb @@ -27,6 +27,7 @@ func TestAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(t *testing.T) { ResourceName: "google_gkeonprem_vmware_node_pool.nodepool", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, { Config: testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(context), @@ -35,6 +36,7 @@ func TestAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(t *testing.T) { ResourceName: "google_gkeonprem_vmware_node_pool.nodepool", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, }, }, }) @@ -92,7 +94,9 @@ func testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdateStart(context map[string name = "tf-test-nodepool-%{random_suffix}" location = "us-west1" vmware_cluster = google_gkeonprem_vmware_cluster.cluster.name - annotations = {} + annotations = { + env = "test" + } config { cpus = 4 memory_mb = 8196 @@ -167,7 +171,9 @@ func testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(context map[string]inte name = "tf-test-nodepool-%{random_suffix}" location = "us-west1" vmware_cluster = google_gkeonprem_vmware_cluster.cluster.name - annotations = {} + annotations = { + env = "test-update" + } config { cpus = 5 memory_mb = 4096 diff --git a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb index 41802a5c5860..da8d40853c23 100644 --- a/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb +++ b/mmv1/third_party/terraform/services/secretmanager/resource_secret_manager_secret_test.go.erb @@ -83,7 +83,7 @@ func TestAccSecretManagerSecret_annotationsUpdate(t *testing.T) { ResourceName: "google_secret_manager_secret.secret-with-annotations", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"ttl"}, + ImportStateVerifyIgnore: []string{"ttl", "labels", "terraform_labels", "annotations"}, }, { Config: testAccSecretManagerSecret_annotationsUpdate(context), @@ -92,7 +92,7 @@ func TestAccSecretManagerSecret_annotationsUpdate(t *testing.T) { ResourceName: "google_secret_manager_secret.secret-with-annotations", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"ttl"}, + ImportStateVerifyIgnore: []string{"ttl", "labels", "terraform_labels", "annotations"}, }, { Config: testAccSecretManagerSecret_annotationsBasic(context), @@ -101,7 +101,7 @@ func TestAccSecretManagerSecret_annotationsUpdate(t *testing.T) { ResourceName: "google_secret_manager_secret.secret-with-annotations", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"ttl"}, + ImportStateVerifyIgnore: []string{"ttl", "labels", "terraform_labels", "annotations"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_cluster_test.go.erb b/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_cluster_test.go.erb index af09534de104..e544f9085579 100644 --- a/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_cluster_test.go.erb +++ b/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_cluster_test.go.erb @@ -28,7 +28,7 @@ func TestAccWorkstationsWorkstationCluster_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, { Config: testAccWorkstationsWorkstationCluster_update(context), @@ -37,7 +37,7 @@ func TestAccWorkstationsWorkstationCluster_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, }, }) @@ -62,7 +62,7 @@ func TestAccWorkstationsWorkstationCluster_Private_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, { Config: testAccWorkstationsWorkstationCluster_private_update(context), @@ -71,7 +71,7 @@ func TestAccWorkstationsWorkstationCluster_Private_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_config_test.go.erb b/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_config_test.go.erb index ebdc135e6095..4a4984fae0d1 100644 --- a/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_config_test.go.erb +++ b/mmv1/third_party/terraform/services/workstations/resource_workstations_workstation_config_test.go.erb @@ -242,7 +242,7 @@ func TestAccWorkstationsWorkstationConfig_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, { Config: testAccWorkstationsWorkstationConfig_update(context), @@ -251,7 +251,7 @@ func TestAccWorkstationsWorkstationConfig_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, { Config: testAccWorkstationsWorkstationConfig_workstationConfigBasicExample(context), @@ -260,7 +260,7 @@ func TestAccWorkstationsWorkstationConfig_update(t *testing.T) { ResourceName: "google_workstations_workstation_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag"}, + ImportStateVerifyIgnore: []string{"etag", "annotations"}, }, }, }) diff --git a/mmv1/third_party/terraform/tpgresource/labels.go b/mmv1/third_party/terraform/tpgresource/labels.go index 06cb72c7c9bb..a0b13c52b78d 100644 --- a/mmv1/third_party/terraform/tpgresource/labels.go +++ b/mmv1/third_party/terraform/tpgresource/labels.go @@ -8,6 +8,20 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) +func FlattenLabels(labels map[string]string, d *schema.ResourceData) map[string]interface{} { + transformed := make(map[string]interface{}) + + if v, ok := d.GetOk("labels"); ok { + if labels != nil { + for k, _ := range v.(map[string]interface{}) { + transformed[k] = labels[k] + } + } + } + + return transformed +} + func SetLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { config := meta.(*transport_tpg.Config) diff --git a/mmv1/third_party/terraform/tpgresource/lables.go b/mmv1/third_party/terraform/tpgresource/lables.go deleted file mode 100644 index 1e76a2aeb35c..000000000000 --- a/mmv1/third_party/terraform/tpgresource/lables.go +++ /dev/null @@ -1,19 +0,0 @@ -package tpgresource - -import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func FlattenLabels(labels map[string]string, d *schema.ResourceData) map[string]interface{} { - transformed := make(map[string]interface{}) - - if v, ok := d.GetOk("labels"); ok { - if labels != nil { - for k, _ := range v.(map[string]interface{}) { - transformed[k] = labels[k] - } - } - } - - return transformed -} From 986547db0dfbd02f299f6f27f21fc471bcce3229 Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Fri, 15 Sep 2023 09:31:50 -0700 Subject: [PATCH 083/476] Bump EdgeCacheService timeout from 30m to 60m (#8962) --- mmv1/products/networkservices/EdgeCacheService.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mmv1/products/networkservices/EdgeCacheService.yaml b/mmv1/products/networkservices/EdgeCacheService.yaml index ff77b8df406e..ac6c6960246a 100644 --- a/mmv1/products/networkservices/EdgeCacheService.yaml +++ b/mmv1/products/networkservices/EdgeCacheService.yaml @@ -26,9 +26,9 @@ async: !ruby/object:Api::OpAsync base_url: '{{op_id}}' wait_ms: 1000 timeouts: !ruby/object:Api::Timeouts - insert_minutes: 30 - update_minutes: 30 - delete_minutes: 30 + insert_minutes: 60 + update_minutes: 60 + delete_minutes: 60 result: !ruby/object:Api::OpAsync::Result path: 'response' status: !ruby/object:Api::OpAsync::Status From dd03c52e3f2b3ccf8c63f7f77436fe5c559a6ea6 Mon Sep 17 00:00:00 2001 From: Nick Elliot Date: Fri, 15 Sep 2023 09:33:39 -0700 Subject: [PATCH 084/476] Upgrade DCL to v1.51.0 (#8876) --- mmv1/third_party/terraform/go.mod.erb | 2 +- mmv1/third_party/terraform/go.sum | 6 +- .../tpgresource/common_diff_suppress.go.erb | 5 ++ .../tpgtools_custom_flattens.go.erb | 40 +++++++++ tools/diff-processor/go.mod | 2 +- tools/diff-processor/go.sum | 4 +- tools/missing-test-detector/go.mod | 2 +- tools/missing-test-detector/go.sum | 4 +- tpgtools/go.mod | 42 ++++++---- tpgtools/go.sum | 83 ++++++++++++++++++- .../containeraws/beta/node_pool.yaml | 14 ++++ .../overrides/containeraws/node_pool.yaml | 14 ++++ .../samples/nodepool/basic.tf.tmpl | 4 + .../samples/nodepool/basic_update.tf.tmpl | 4 + .../samples/nodepool/beta_basic.tf.tmpl | 4 + .../nodepool/beta_basic_update.tf.tmpl | 4 + .../containeraws/samples/nodepool/meta.yaml | 3 + .../containerazure/beta/node_pool.yaml | 14 ++++ .../overrides/containerazure/node_pool.yaml | 14 ++++ .../samples/nodepool/basic.tf.tmpl | 4 + .../samples/nodepool/basic_update.tf.tmpl | 4 + .../samples/nodepool/beta_basic.tf.tmpl | 4 + .../nodepool/beta_basic_update.tf.tmpl | 4 + .../containerazure/samples/nodepool/meta.yaml | 4 + .../samples/spoke/linked_vpc_network.tf.tmpl | 30 +++++++ .../samples/spoke/linked_vpc_network.yaml | 13 +++ 26 files changed, 299 insertions(+), 29 deletions(-) create mode 100644 mmv1/third_party/terraform/tpgresource/tpgtools_custom_flattens.go.erb create mode 100644 tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.tf.tmpl create mode 100644 tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.yaml diff --git a/mmv1/third_party/terraform/go.mod.erb b/mmv1/third_party/terraform/go.mod.erb index 13b659db12a6..db246d4dfd1a 100644 --- a/mmv1/third_party/terraform/go.mod.erb +++ b/mmv1/third_party/terraform/go.mod.erb @@ -4,7 +4,7 @@ go 1.19 require ( cloud.google.com/go/bigtable v1.19.0 - github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0 + github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 github.com/apparentlymart/go-cidr v1.1.0 github.com/davecgh/go-spew v1.1.1 github.com/dnaeon/go-vcr v1.0.1 diff --git a/mmv1/third_party/terraform/go.sum b/mmv1/third_party/terraform/go.sum index 205203241069..f1131ffa5f89 100644 --- a/mmv1/third_party/terraform/go.sum +++ b/mmv1/third_party/terraform/go.sum @@ -15,8 +15,8 @@ cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+K cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI= cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0 h1:tsuB2FrGmDXIPUdhRD6YdUuvIzAly6+RYpyRkKWwk9E= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 h1:YhWTPhOf6gVpA9mSfnLOuL8Y6j8W5pzmHE7flXjTke4= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= @@ -466,3 +466,5 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 h1:YhWTPhOf6gVpA9mSfnLOuL8Y6j8W5pzmHE7flXjTke4= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= diff --git a/mmv1/third_party/terraform/tpgresource/common_diff_suppress.go.erb b/mmv1/third_party/terraform/tpgresource/common_diff_suppress.go.erb index b02b0204f400..86ced35209ab 100644 --- a/mmv1/third_party/terraform/tpgresource/common_diff_suppress.go.erb +++ b/mmv1/third_party/terraform/tpgresource/common_diff_suppress.go.erb @@ -55,6 +55,11 @@ func EmptyOrDefaultStringSuppress(defaultVal string) schema.SchemaDiffSuppressFu } } +func EmptyOrFalseSuppressBoolean(k, old, new string, d *schema.ResourceData) bool { + o, n := d.GetChange(k) + return (o == nil && !n.(bool)) +} + func IpCidrRangeDiffSuppress(k, old, new string, d *schema.ResourceData) bool { // The range may be a: // A) single IP address (e.g. 10.2.3.4) diff --git a/mmv1/third_party/terraform/tpgresource/tpgtools_custom_flattens.go.erb b/mmv1/third_party/terraform/tpgresource/tpgtools_custom_flattens.go.erb new file mode 100644 index 000000000000..744d61c084ed --- /dev/null +++ b/mmv1/third_party/terraform/tpgresource/tpgtools_custom_flattens.go.erb @@ -0,0 +1,40 @@ +<% autogen_exception -%> +package tpgresource + +import ( + containeraws "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/containeraws<%= dcl_version(version) -%>" + containerazure "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/containerazure<%= dcl_version(version) -%>" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func FlattenContainerAwsNodePoolManagement(obj *containeraws.NodePoolManagement, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if obj == nil { + return nil + } + transformed := make(map[string]interface{}) + + if obj.AutoRepair == nil || obj.Empty() { + transformed["auto_repair"] = false + } else { + transformed["auto_repair"] = obj.AutoRepair + } + + return []interface{}{transformed} +} + +func FlattenContainerAzureNodePoolManagement(obj *containerazure.NodePoolManagement, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if obj == nil { + return nil + } + transformed := make(map[string]interface{}) + + if obj.AutoRepair == nil || obj.Empty() { + transformed["auto_repair"] = false + } else { + transformed["auto_repair"] = obj.AutoRepair + } + + return []interface{}{transformed} +} diff --git a/tools/diff-processor/go.mod b/tools/diff-processor/go.mod index 37ae5ef32752..92d513b193cd 100644 --- a/tools/diff-processor/go.mod +++ b/tools/diff-processor/go.mod @@ -24,7 +24,7 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.0 // indirect cloud.google.com/go/longrunning v0.5.1 // indirect - github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0 // indirect + github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect diff --git a/tools/diff-processor/go.sum b/tools/diff-processor/go.sum index d7166b77e319..8e301bf72f63 100644 --- a/tools/diff-processor/go.sum +++ b/tools/diff-processor/go.sum @@ -15,8 +15,8 @@ cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5 cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI= cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0 h1:tsuB2FrGmDXIPUdhRD6YdUuvIzAly6+RYpyRkKWwk9E= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 h1:YhWTPhOf6gVpA9mSfnLOuL8Y6j8W5pzmHE7flXjTke4= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= diff --git a/tools/missing-test-detector/go.mod b/tools/missing-test-detector/go.mod index 5572d08961d0..291b412ade2c 100644 --- a/tools/missing-test-detector/go.mod +++ b/tools/missing-test-detector/go.mod @@ -23,7 +23,7 @@ require ( cloud.google.com/go/compute/metadata v0.2.2 // indirect cloud.google.com/go/iam v0.8.0 // indirect cloud.google.com/go/longrunning v0.3.0 // indirect - github.com/GoogleCloudPlatform/declarative-resource-client-library v1.34.0 // indirect + github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect diff --git a/tools/missing-test-detector/go.sum b/tools/missing-test-detector/go.sum index 3a78829e6b16..9200a80bcd61 100644 --- a/tools/missing-test-detector/go.sum +++ b/tools/missing-test-detector/go.sum @@ -15,8 +15,8 @@ cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGE cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.34.0 h1:o7t+hPFv+Ax5O2vxzIH7dEtvlWA7JJOlOd7mWFvMa6s= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.34.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 h1:YhWTPhOf6gVpA9mSfnLOuL8Y6j8W5pzmHE7flXjTke4= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= diff --git a/tpgtools/go.mod b/tpgtools/go.mod index 01564e2fc660..edb1c068553e 100644 --- a/tpgtools/go.mod +++ b/tpgtools/go.mod @@ -3,26 +3,30 @@ module github.com/GoogleCloudPlatform/magic-modules/tpgtools go 1.19 require ( - bitbucket.org/creachadair/stringset v0.0.9 - github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0 - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + bitbucket.org/creachadair/stringset v0.0.11 + github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 + github.com/golang/glog v1.1.2 github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.0 github.com/kylelemons/godebug v1.1.0 - github.com/nasa9084/go-openapi v0.0.0-20200604141640-2875b7376353 + github.com/nasa9084/go-openapi v0.0.0-20210722142352-4a81d737faf6 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.61.0 // indirect + cloud.google.com/go v0.110.6 // indirect + cloud.google.com/go/compute v1.23.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg v1.0.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - github.com/golang/protobuf v1.4.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cpy v0.0.0-20211218193943-a9c933c06932 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect github.com/hashicorp/go-multierror v1.0.0 // indirect github.com/hashicorp/go-uuid v1.0.1 // indirect @@ -36,14 +40,16 @@ require ( github.com/mitchellh/reflectwalk v1.0.1 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/zclconf/go-cty v1.2.1 // indirect - go.opencensus.io v0.22.4 // indirect - golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect - golang.org/x/text v0.3.3 // indirect - google.golang.org/api v0.29.0 // indirect - google.golang.org/appengine v1.6.6 // indirect - google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect - google.golang.org/grpc v1.32.0 // indirect - google.golang.org/protobuf v1.25.0 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/crypto v0.13.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/api v0.138.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.57.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect ) diff --git a/tpgtools/go.sum b/tpgtools/go.sum index 7018bea809e0..e0e118ffa9fc 100644 --- a/tpgtools/go.sum +++ b/tpgtools/go.sum @@ -1,5 +1,7 @@ bitbucket.org/creachadair/stringset v0.0.9 h1:L4vld9nzPt90UZNrXjNelTshD74ps4P5NGs3Iq6yN3o= bitbucket.org/creachadair/stringset v0.0.9/go.mod h1:t+4WcQ4+PXTa8aQdNKe40ZP6iwesoMFWAxPGd3UGjyY= +bitbucket.org/creachadair/stringset v0.0.11 h1:6Sv4CCv14Wm+OipW4f3tWOb0SQVpBDLW0knnJqUnmZ8= +bitbucket.org/creachadair/stringset v0.0.11/go.mod h1:wh0BHewFe+j0HrzWz7KcGbSNpFzWwnpmgPRlB57U5jU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -15,12 +17,18 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.61.0 h1:NLQf5e1OMspfNT1RAHOB3ublr1TW3YTXO8OiWwVjK2U= cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= +cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q= +cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -35,8 +43,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0 h1:tsuB2FrGmDXIPUdhRD6YdUuvIzAly6+RYpyRkKWwk9E= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.50.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0 h1:YhWTPhOf6gVpA9mSfnLOuL8Y6j8W5pzmHE7flXjTke4= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.51.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= @@ -90,10 +98,14 @@ github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -115,6 +127,11 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -125,8 +142,12 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cpy v0.0.0-20211218193943-a9c933c06932 h1:5/4TSDzpDnHQ8rKEEQBjRlYx77mHOvXu08oGchxej7o= github.com/google/go-cpy v0.0.0-20211218193943-a9c933c06932/go.mod h1:cC6EdPbj/17GFCPDK39NRarlMI+kt+O60S12cNB5J9Y= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -139,6 +160,12 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= @@ -226,6 +253,8 @@ github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY7 github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/nasa9084/go-openapi v0.0.0-20200604141640-2875b7376353 h1:B12KiVODig0ltyL7AOeO68ZKLrIWAus/SdlWvO7KcfA= github.com/nasa9084/go-openapi v0.0.0-20200604141640-2875b7376353/go.mod h1:Y+QYE2No9P7gTzq/clACcx4vZ34gemXUmfspIcRD6LY= +github.com/nasa9084/go-openapi v0.0.0-20210722142352-4a81d737faf6 h1:EgeFHuf1nYbw8nN/04bzCHjUL+ZGOMi+b5DXH+TVNJE= +github.com/nasa9084/go-openapi v0.0.0-20210722142352-4a81d737faf6/go.mod h1:oY7A58oP7/O7+8Ob5s6uGrdVlLQj/BGgUUIsj6IMrQw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= @@ -241,10 +270,15 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -254,6 +288,7 @@ github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0B github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= @@ -264,6 +299,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -272,6 +309,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -302,6 +342,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -330,12 +371,19 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -344,6 +392,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -374,12 +423,25 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -421,6 +483,7 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -440,6 +503,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.138.0 h1:K/tVp05MxNVbHShRw9m7e9VJGdagNeTdMzqPH7AUqr0= +google.golang.org/api v0.138.0/go.mod h1:4xyob8CxC+0GChNBvEUAk8VBKNvYOTWM9T3v3UfRxuY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -447,6 +512,8 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -476,6 +543,10 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc= google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -490,6 +561,9 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -501,6 +575,10 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -515,6 +593,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tpgtools/overrides/containeraws/beta/node_pool.yaml b/tpgtools/overrides/containeraws/beta/node_pool.yaml index e16b502f32ef..e3742c97ecf1 100644 --- a/tpgtools/overrides/containeraws/beta/node_pool.yaml +++ b/tpgtools/overrides/containeraws/beta/node_pool.yaml @@ -10,3 +10,17 @@ field: config.instance_placement.tenancy details: diffsuppressfunc: tpgresource.CompareCaseInsensitive +- type: CUSTOM_STATE_SETTER + field: management + details: + function: d.Set("management", tpgresource.FlattenContainerAwsNodePoolManagement(res.Management, d, config)) +- type: CUSTOM_SCHEMA_VALUES + field: management + details: + optional: true + computed: true +- type: CUSTOM_SCHEMA_VALUES + field: management.auto_repair + details: + optional: true + computed: true diff --git a/tpgtools/overrides/containeraws/node_pool.yaml b/tpgtools/overrides/containeraws/node_pool.yaml index 4f76c9df9c1e..bb9479ee716e 100644 --- a/tpgtools/overrides/containeraws/node_pool.yaml +++ b/tpgtools/overrides/containeraws/node_pool.yaml @@ -6,3 +6,17 @@ field: config.taints.effect details: diffsuppressfunc: tpgresource.CompareCaseInsensitive +- type: CUSTOM_STATE_SETTER + field: management + details: + function: d.Set("management", tpgresource.FlattenContainerAwsNodePoolManagement(res.Management, d, config)) +- type: CUSTOM_SCHEMA_VALUES + field: management + details: + optional: true + computed: true +- type: CUSTOM_SCHEMA_VALUES + field: management.auto_repair + details: + optional: true + computed: true diff --git a/tpgtools/overrides/containeraws/samples/nodepool/basic.tf.tmpl b/tpgtools/overrides/containeraws/samples/nodepool/basic.tf.tmpl index abb995117a02..fd11ead5739d 100644 --- a/tpgtools/overrides/containeraws/samples/nodepool/basic.tf.tmpl +++ b/tpgtools/overrides/containeraws/samples/nodepool/basic.tf.tmpl @@ -146,6 +146,10 @@ resource "google_container_aws_node_pool" "primary" { label-one = "value-one" } + management { + auto_repair = true + } + project = "{{project}}" } diff --git a/tpgtools/overrides/containeraws/samples/nodepool/basic_update.tf.tmpl b/tpgtools/overrides/containeraws/samples/nodepool/basic_update.tf.tmpl index 85c7870fbf1c..d7a2cb9aab28 100644 --- a/tpgtools/overrides/containeraws/samples/nodepool/basic_update.tf.tmpl +++ b/tpgtools/overrides/containeraws/samples/nodepool/basic_update.tf.tmpl @@ -145,6 +145,10 @@ resource "google_container_aws_node_pool" "primary" { label-two = "value-two" } + management { + auto_repair = false + } + project = "{{project}}" } diff --git a/tpgtools/overrides/containeraws/samples/nodepool/beta_basic.tf.tmpl b/tpgtools/overrides/containeraws/samples/nodepool/beta_basic.tf.tmpl index 58252330d551..cc4db2389621 100644 --- a/tpgtools/overrides/containeraws/samples/nodepool/beta_basic.tf.tmpl +++ b/tpgtools/overrides/containeraws/samples/nodepool/beta_basic.tf.tmpl @@ -150,6 +150,10 @@ resource "google_container_aws_node_pool" "primary" { name = "{{node-pool-name}}" subnet_id = "{{aws_subnet}}" version = "${data.google_container_aws_versions.versions.valid_versions[0]}" + + management { + auto_repair = true + } annotations = { label-one = "value-one" diff --git a/tpgtools/overrides/containeraws/samples/nodepool/beta_basic_update.tf.tmpl b/tpgtools/overrides/containeraws/samples/nodepool/beta_basic_update.tf.tmpl index 13037629cb09..42d8c055dbef 100644 --- a/tpgtools/overrides/containeraws/samples/nodepool/beta_basic_update.tf.tmpl +++ b/tpgtools/overrides/containeraws/samples/nodepool/beta_basic_update.tf.tmpl @@ -150,6 +150,10 @@ resource "google_container_aws_node_pool" "primary" { subnet_id = "{{aws_subnet}}" version = "${data.google_container_aws_versions.versions.valid_versions[0]}" + management { + auto_repair = false + } + annotations = { label-two = "value-two" } diff --git a/tpgtools/overrides/containeraws/samples/nodepool/meta.yaml b/tpgtools/overrides/containeraws/samples/nodepool/meta.yaml index 1f3464c256a4..b14ec31e9af2 100644 --- a/tpgtools/overrides/containeraws/samples/nodepool/meta.yaml +++ b/tpgtools/overrides/containeraws/samples/nodepool/meta.yaml @@ -1,4 +1,7 @@ ignore_read: - fleet.0.project + - management.# + - management.0.% + - management.0.auto_repair doc_hide: - beta_basic.tf.tmpl diff --git a/tpgtools/overrides/containerazure/beta/node_pool.yaml b/tpgtools/overrides/containerazure/beta/node_pool.yaml index e69de29bb2d1..62a7815cb0d4 100644 --- a/tpgtools/overrides/containerazure/beta/node_pool.yaml +++ b/tpgtools/overrides/containerazure/beta/node_pool.yaml @@ -0,0 +1,14 @@ +- type: CUSTOM_STATE_SETTER + field: management + details: + function: d.Set("management", tpgresource.FlattenContainerAzureNodePoolManagement(res.Management, d, config)) +- type: CUSTOM_SCHEMA_VALUES + field: management + details: + optional: true + computed: true +- type: CUSTOM_SCHEMA_VALUES + field: management.auto_repair + details: + optional: true + computed: true diff --git a/tpgtools/overrides/containerazure/node_pool.yaml b/tpgtools/overrides/containerazure/node_pool.yaml index e69de29bb2d1..62a7815cb0d4 100644 --- a/tpgtools/overrides/containerazure/node_pool.yaml +++ b/tpgtools/overrides/containerazure/node_pool.yaml @@ -0,0 +1,14 @@ +- type: CUSTOM_STATE_SETTER + field: management + details: + function: d.Set("management", tpgresource.FlattenContainerAzureNodePoolManagement(res.Management, d, config)) +- type: CUSTOM_SCHEMA_VALUES + field: management + details: + optional: true + computed: true +- type: CUSTOM_SCHEMA_VALUES + field: management.auto_repair + details: + optional: true + computed: true diff --git a/tpgtools/overrides/containerazure/samples/nodepool/basic.tf.tmpl b/tpgtools/overrides/containerazure/samples/nodepool/basic.tf.tmpl index 9130e0b68e42..8ea45ee3f996 100644 --- a/tpgtools/overrides/containerazure/samples/nodepool/basic.tf.tmpl +++ b/tpgtools/overrides/containerazure/samples/nodepool/basic.tf.tmpl @@ -90,6 +90,10 @@ resource "google_container_azure_node_pool" "primary" { annotation-one = "value-one" } + management { + auto_repair = true + } + project = "{{project}}" } diff --git a/tpgtools/overrides/containerazure/samples/nodepool/basic_update.tf.tmpl b/tpgtools/overrides/containerazure/samples/nodepool/basic_update.tf.tmpl index 31b230b5c09f..2786c74963b7 100644 --- a/tpgtools/overrides/containerazure/samples/nodepool/basic_update.tf.tmpl +++ b/tpgtools/overrides/containerazure/samples/nodepool/basic_update.tf.tmpl @@ -91,6 +91,10 @@ resource "google_container_azure_node_pool" "primary" { annotation-two = "value-two" } + management { + auto_repair = false + } + project = "{{project}}" } diff --git a/tpgtools/overrides/containerazure/samples/nodepool/beta_basic.tf.tmpl b/tpgtools/overrides/containerazure/samples/nodepool/beta_basic.tf.tmpl index ff9cb4c233db..4967311d5107 100644 --- a/tpgtools/overrides/containerazure/samples/nodepool/beta_basic.tf.tmpl +++ b/tpgtools/overrides/containerazure/samples/nodepool/beta_basic.tf.tmpl @@ -92,6 +92,10 @@ resource "google_container_azure_node_pool" "primary" { subnet_id = "/subscriptions/{{azure_subscription}}/resourceGroups/{{byo_multicloud_prefix}}-dev-byo/providers/Microsoft.Network/virtualNetworks/{{byo_multicloud_prefix}}-dev-vnet/subnets/default" version = "${data.google_container_azure_versions.versions.valid_versions[0]}" + management { + auto_repair = true + } + annotations = { annotation-one = "value-one" } diff --git a/tpgtools/overrides/containerazure/samples/nodepool/beta_basic_update.tf.tmpl b/tpgtools/overrides/containerazure/samples/nodepool/beta_basic_update.tf.tmpl index 2aef4c024ba4..2156af0dc662 100644 --- a/tpgtools/overrides/containerazure/samples/nodepool/beta_basic_update.tf.tmpl +++ b/tpgtools/overrides/containerazure/samples/nodepool/beta_basic_update.tf.tmpl @@ -93,6 +93,10 @@ resource "google_container_azure_node_pool" "primary" { subnet_id = "/subscriptions/{{azure_subscription}}/resourceGroups/{{byo_multicloud_prefix}}-dev-byo/providers/Microsoft.Network/virtualNetworks/{{byo_multicloud_prefix}}-dev-vnet/subnets/default" version = "${data.google_container_azure_versions.versions.valid_versions[0]}" + management { + auto_repair = false + } + annotations = { annotation-two = "value-two" } diff --git a/tpgtools/overrides/containerazure/samples/nodepool/meta.yaml b/tpgtools/overrides/containerazure/samples/nodepool/meta.yaml index 0e7b5556a993..09bdf3c9ce82 100644 --- a/tpgtools/overrides/containerazure/samples/nodepool/meta.yaml +++ b/tpgtools/overrides/containerazure/samples/nodepool/meta.yaml @@ -1,2 +1,6 @@ +ignore_read: + - management.# + - management.0.% + - management.0.auto_repair doc_hide: - beta_basic.tf.tmpl \ No newline at end of file diff --git a/tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.tf.tmpl b/tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.tf.tmpl new file mode 100644 index 000000000000..8a1bd423b3bb --- /dev/null +++ b/tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.tf.tmpl @@ -0,0 +1,30 @@ + +resource "google_compute_network" "network" { + name = "{{network}}" + auto_create_subnetworks = false +} + +resource "google_network_connectivity_hub" "basic_hub" { + name = "{{hub}}" + description = "A sample hub" + labels = { + label-two = "value-one" + } +} + +resource "google_network_connectivity_spoke" "primary" { + name = "{{name}}" + location = "global" + description = "A sample spoke with a linked routher appliance instance" + labels = { + label-one = "value-one" + } + hub = google_network_connectivity_hub.basic_hub.id + linked_vpc_network { + exclude_export_ranges = [ + "198.51.100.0/24", + "10.10.0.0/16" + ] + uri = google_compute_network.network.self_link + } +} \ No newline at end of file diff --git a/tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.yaml b/tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.yaml new file mode 100644 index 000000000000..ec8fa78bb2fd --- /dev/null +++ b/tpgtools/overrides/networkconnectivity/samples/spoke/linked_vpc_network.yaml @@ -0,0 +1,13 @@ +updates: + - resource: linked_vpc_network.tf.tmpl +variables: + - name: "project" + type: "project" + - name: "region" + type: "region" + - name: "name" + type: "resource_name" + - name: "hub" + type: "resource_name" + - name: "network" + type: "resource_name" From e3ab99a109535ac515b61d87111f000a57c9e0a5 Mon Sep 17 00:00:00 2001 From: abheda-crest <105624942+abheda-crest@users.noreply.github.com> Date: Fri, 15 Sep 2023 23:31:15 +0530 Subject: [PATCH 085/476] Added guides for breaking change for automatic field in google_secret_manager_secret resource (#8680) --- .../guides/version_5_upgrade.html.markdown | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown index ea8677a03b5c..2d6fc46cec1d 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown @@ -469,3 +469,33 @@ If you were relying on accessing an individual flag by index (for example, `goog ### `Create` endpoint is used to create the resource `google_service_networking_connection` now uses the Create endpoint instead of the Patch endpoint during the creation step. Previously, Patch was used as a workaround for an issue that has since been resolved. + +## Resource: `google_secret_manager_secret` + +### `replication.automatic` is now removed + +Deprecated in favor of field `replication.auto`. It is now removed. + +#### Old Config + +```hcl +resource "google_secret_manager_secret" "my-secret" { + secret_id = "tf-secret" + + replication { + automatic = true + } +} +``` + +#### New Config + +```hcl +resource "google_secret_manager_secret" "my-secret" { + secret_id = "tf-secret" + + replication { + auto {} + } +} +``` From 5545a72c431f919958b6531bf847384767403924 Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Fri, 15 Sep 2023 13:19:31 -0500 Subject: [PATCH 086/476] upgrade guide - container cluster removals (#8968) --- .../docs/guides/version_5_upgrade.html.markdown | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown index 2d6fc46cec1d..7264d81c38b1 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown @@ -277,6 +277,17 @@ These two unsupported fields were introduced incorrectly. They are now removed. This unsupported field was introduced incorrectly. It is now removed. +## Resource: `google_container_cluster` + +### `enable_binary_authorization` is now removed + +`enable_binary_authorization` has been removed in favor of `binary_authorization.enabled`. + +### Default value of `network_policy.provider` is now removed + +Previously `network_policy.provider` defaulted to "PROVIDER_UNSPECIFIED". It no longer +has a default value. + ## Resource: `google_dataplex_datascan` ### `dataQualityResult` and `dataProfileResult` output fields are now removed From 1a32f8d83008febd8f76b81aebf53742b6ffc660 Mon Sep 17 00:00:00 2001 From: Cameron Thornton Date: Fri, 15 Sep 2023 13:19:42 -0500 Subject: [PATCH 087/476] remove container cluster `enable_binary_authorization` (#8784) --- .../resource_container_cluster.go.erb | 82 ++++++++----------- .../resource_container_cluster_test.go.erb | 45 ---------- .../docs/r/container_cluster.html.markdown | 4 - mmv1/third_party/tgc/container.go | 10 --- .../example_container_cluster.tfplan.json | 4 +- .../tgc/tests/data/full_container_cluster.tf | 1 - .../data/full_container_cluster.tfplan.json | 4 +- 7 files changed, 34 insertions(+), 116 deletions(-) diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb index 19b8c98d860b..d031f130dcd0 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb @@ -780,40 +780,31 @@ func ResourceContainerCluster() *schema.Resource { Description: ` Description of the cluster.`, }, - "enable_binary_authorization": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Deprecated: "Deprecated in favor of binary_authorization.", - Description: `Enable Binary Authorization for this cluster. If enabled, all container images will be validated by Google Binary Authorization.`, - ConflictsWith: []string{"enable_autopilot", "binary_authorization"}, + "binary_authorization": { + Type: schema.TypeList, + Optional: true, + DiffSuppressFunc: BinaryAuthorizationDiffSuppress, + MaxItems: 1, + Description: "Configuration options for the Binary Authorization feature.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Deprecated: "Deprecated in favor of evaluation_mode.", + Description: "Enable Binary Authorization for this cluster.", + ConflictsWith: []string{"enable_autopilot", "binary_authorization.0.evaluation_mode"}, + }, + "evaluation_mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"DISABLED", "PROJECT_SINGLETON_POLICY_ENFORCE"}, false), + Description: "Mode of operation for Binary Authorization policy evaluation.", + ConflictsWith: []string{"binary_authorization.0.enabled"}, + }, + }, + }, }, - "binary_authorization": { - Type: schema.TypeList, - Optional: true, - DiffSuppressFunc: BinaryAuthorizationDiffSuppress, - MaxItems: 1, - Description: "Configuration options for the Binary Authorization feature.", - ConflictsWith: []string{"enable_binary_authorization"}, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Deprecated: "Deprecated in favor of evaluation_mode.", - Description: "Enable Binary Authorization for this cluster.", - ConflictsWith: []string{"enable_autopilot", "binary_authorization.0.evaluation_mode"}, - }, - "evaluation_mode": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{"DISABLED", "PROJECT_SINGLETON_POLICY_ENFORCE"}, false), - Description: "Mode of operation for Binary Authorization policy evaluation.", - ConflictsWith: []string{"binary_authorization.0.enabled"}, - }, - }, - }, - }, "enable_kubernetes_alpha": { Type: schema.TypeBool, @@ -2154,7 +2145,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er PodSecurityPolicyConfig: expandPodSecurityPolicyConfig(d.Get("pod_security_policy_config")), <% end -%> Autoscaling: expandClusterAutoscaling(d.Get("cluster_autoscaling"), d), - BinaryAuthorization: expandBinaryAuthorization(d.Get("binary_authorization"), d.Get("enable_binary_authorization").(bool)), + BinaryAuthorization: expandBinaryAuthorization(d.Get("binary_authorization")), Autopilot: &container.Autopilot{ Enabled: d.Get("enable_autopilot").(bool), WorkloadPolicyConfig: workloadPolicyConfig, @@ -2638,19 +2629,10 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro } if err := d.Set("cluster_autoscaling", flattenClusterAutoscaling(cluster.Autoscaling)); err != nil { return err - } - binauthz_enabled := d.Get("binary_authorization.0.enabled").(bool) - legacy_binauthz_enabled := d.Get("enable_binary_authorization").(bool) - if !binauthz_enabled { - if err := d.Set("enable_binary_authorization", cluster.BinaryAuthorization != nil && cluster.BinaryAuthorization.Enabled); err != nil { - return fmt.Errorf("Error setting enable_binary_authorization: %s", err) - } - } - if !legacy_binauthz_enabled { - if err := d.Set("binary_authorization", flattenBinaryAuthorization(cluster.BinaryAuthorization)); err != nil { - return err - } - } + } + if err := d.Set("binary_authorization", flattenBinaryAuthorization(cluster.BinaryAuthorization)); err != nil { + return err + } if autopilot := cluster.Autopilot; autopilot != nil { if err := d.Set("enable_autopilot", autopilot.Enabled); err != nil { return fmt.Errorf("Error setting enable_autopilot: %s", err) @@ -3004,7 +2986,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er if d.HasChange("binary_authorization") { req := &container.UpdateClusterRequest{ Update: &container.ClusterUpdate{ - DesiredBinaryAuthorization: expandBinaryAuthorization(d.Get("binary_authorization"), d.Get("enable_binary_authorization").(bool)), + DesiredBinaryAuthorization: expandBinaryAuthorization(d.Get("binary_authorization")), }, } @@ -4830,11 +4812,11 @@ func expandNotificationConfig(configured interface{}) *container.NotificationCon } } -func expandBinaryAuthorization(configured interface{}, legacy_enabled bool) *container.BinaryAuthorization { +func expandBinaryAuthorization(configured interface{}) *container.BinaryAuthorization { l := configured.([]interface{}) if len(l) == 0 || l[0] == nil { return &container.BinaryAuthorization{ - Enabled: legacy_enabled, + Enabled: false, ForceSendFields: []string{"Enabled"}, } } diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb index 91f4c3b4e3ea..6b0db114d9dd 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb @@ -3074,7 +3074,6 @@ func TestAccContainerCluster_withBinaryAuthorizationEnabledBool(t *testing.T) { ResourceName: "google_container_cluster.with_binary_authorization_enabled_bool", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"enable_binary_authorization"}, }, { Config: testAccContainerCluster_withBinaryAuthorizationEnabledBool(clusterName, false), @@ -3088,38 +3087,6 @@ func TestAccContainerCluster_withBinaryAuthorizationEnabledBool(t *testing.T) { }) } -func TestAccContainerCluster_withBinaryAuthorizationEnabledBoolLegacy(t *testing.T) { - t.Parallel() - - clusterName := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10)) - - acctest.VcrTest(t, resource.TestCase{ - PreCheck: func() { acctest.AccTestPreCheck(t) }, - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), - CheckDestroy: testAccCheckContainerClusterDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testAccContainerCluster_withBinaryAuthorizationEnabledBoolLegacy(clusterName, true), - }, - { - ResourceName: "google_container_cluster.with_binary_authorization_enabled_bool_legacy", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"enable_binary_authorization", "binary_authorization.#", "binary_authorization.0.%", "binary_authorization.0.enabled", "binary_authorization.0.evaluation_mode"}, - }, - { - Config: testAccContainerCluster_withBinaryAuthorizationEnabledBoolLegacy(clusterName, false), - }, - { - ResourceName: "google_container_cluster.with_binary_authorization_enabled_bool_legacy", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"enable_binary_authorization"}, - }, - }, - }) -} - func TestAccContainerCluster_withBinaryAuthorizationEvaluationModeAutopilot(t *testing.T) { t.Parallel() @@ -7197,18 +7164,6 @@ resource "google_container_cluster" "with_binary_authorization_enabled_bool" { `, clusterName, enabled) } -func testAccContainerCluster_withBinaryAuthorizationEnabledBoolLegacy(clusterName string, enabled bool) string { - return fmt.Sprintf(` -resource "google_container_cluster" "with_binary_authorization_enabled_bool_legacy" { - name = "%s" - location = "us-central1-a" - initial_node_count = 1 - - enable_binary_authorization = %v -} -`, clusterName, enabled) -} - func testAccContainerCluster_withBinaryAuthorizationEvaluationMode(clusterName string, autopilot_enabled bool, evaluation_mode string) string { return fmt.Sprintf(` resource "google_container_cluster" "with_binary_authorization_evaluation_mode" { diff --git a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown index e5eb29fe4011..d8fccdc7eb5d 100644 --- a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -156,10 +156,6 @@ per node in this cluster. This doesn't work on "routes-based" clusters, clusters that don't have IP Aliasing enabled. See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/flexible-pod-cidr) for more information. -* `enable_binary_authorization` - (DEPRECATED) Enable Binary Authorization for this cluster. - If enabled, all container images will be validated by Google Binary Authorization. - Deprecated in favor of `binary_authorization`. - * `enable_kubernetes_alpha` - (Optional) Whether to enable Kubernetes Alpha features for this cluster. Note that when this option is enabled, the cluster cannot be upgraded and will be automatically deleted after 30 days. diff --git a/mmv1/third_party/tgc/container.go b/mmv1/third_party/tgc/container.go index 86085212e70f..806b64e228b4 100644 --- a/mmv1/third_party/tgc/container.go +++ b/mmv1/third_party/tgc/container.go @@ -47,10 +47,6 @@ func expandContainerClusterEnableLegacyAbac(v interface{}, d tpgresource.Terrafo return expandContainerEnabledObject(v, d, config) } -func expandContainerClusterEnableBinaryAuthorization(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return expandContainerEnabledObject(v, d, config) -} - func expandContainerMaxPodsConstraint(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { if val := reflect.ValueOf(v); !val.IsValid() || tpgresource.IsEmptyValue(val) { return nil, nil @@ -126,12 +122,6 @@ func GetContainerClusterCaiObject(d tpgresource.TerraformResourceData, config *t func GetContainerClusterApiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]interface{}, error) { obj := make(map[string]interface{}) - binaryAuthorizationProp, err := expandContainerClusterEnableBinaryAuthorization(d.Get("enable_binary_authorization"), d, config) - if err != nil { - return nil, err - } else if v, ok := d.GetOkExists("enable_binary_authorization"); !tpgresource.IsEmptyValue(reflect.ValueOf(binaryAuthorizationProp)) && (ok || !reflect.DeepEqual(v, binaryAuthorizationProp)) { - obj["binaryAuthorization"] = binaryAuthorizationProp - } enableKubernetesAlphaProp, err := expandContainerClusterEnableKubernetesAlpha(d.Get("enable_kubernetes_alpha"), d, config) if err != nil { return nil, err diff --git a/mmv1/third_party/tgc/tests/data/example_container_cluster.tfplan.json b/mmv1/third_party/tgc/tests/data/example_container_cluster.tfplan.json index 998e197fae0d..1f54b16a9b4e 100644 --- a/mmv1/third_party/tgc/tests/data/example_container_cluster.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/example_container_cluster.tfplan.json @@ -13,7 +13,6 @@ "schema_version": 1, "values": { "description": null, - "enable_binary_authorization": false, "enable_intranode_visibility": null, "enable_kubernetes_alpha": false, "enable_legacy_abac": false, @@ -98,7 +97,6 @@ "before": null, "after": { "description": null, - "enable_binary_authorization": false, "enable_intranode_visibility": null, "enable_kubernetes_alpha": false, "enable_legacy_abac": false, @@ -344,4 +342,4 @@ ] } } -} +} \ No newline at end of file diff --git a/mmv1/third_party/tgc/tests/data/full_container_cluster.tf b/mmv1/third_party/tgc/tests/data/full_container_cluster.tf index fe7966114c5e..b43baca7f928 100644 --- a/mmv1/third_party/tgc/tests/data/full_container_cluster.tf +++ b/mmv1/third_party/tgc/tests/data/full_container_cluster.tf @@ -36,7 +36,6 @@ resource "google_container_cluster" "full_list_default_1" { # authenticator_groups_config # cluster_autoscaling # database_encryption - # enable_binary_authorization # enable_intranode_visibility # enable_shielded_nodes # enable_tpu diff --git a/mmv1/third_party/tgc/tests/data/full_container_cluster.tfplan.json b/mmv1/third_party/tgc/tests/data/full_container_cluster.tfplan.json index a9370d3d5cc1..f7074cc4d604 100644 --- a/mmv1/third_party/tgc/tests/data/full_container_cluster.tfplan.json +++ b/mmv1/third_party/tgc/tests/data/full_container_cluster.tfplan.json @@ -34,7 +34,6 @@ "default_max_pods_per_node": 42, "description": "test-description", "enable_autopilot": null, - "enable_binary_authorization": false, "enable_kubernetes_alpha": true, "enable_legacy_abac": true, "enable_shielded_nodes": true, @@ -277,7 +276,6 @@ "default_max_pods_per_node": 42, "description": "test-description", "enable_autopilot": null, - "enable_binary_authorization": false, "enable_kubernetes_alpha": true, "enable_legacy_abac": true, "enable_shielded_nodes": true, @@ -815,4 +813,4 @@ ] } } -} +} \ No newline at end of file From 4c353260a556d4d3ef2a50a90999117f2f9e5182 Mon Sep 17 00:00:00 2001 From: vivianrwu Date: Fri, 15 Sep 2023 12:50:46 -0700 Subject: [PATCH 088/476] Promote tpu-topology to GA (#8953) --- mmv1/third_party/terraform/go.mod.erb | 6 +-- mmv1/third_party/terraform/go.sum | 50 +++---------------- .../resource_container_node_pool.go.erb | 6 --- .../resource_container_node_pool_test.go.erb | 6 +-- .../docs/r/container_node_pool.html.markdown | 2 +- 5 files changed, 13 insertions(+), 57 deletions(-) diff --git a/mmv1/third_party/terraform/go.mod.erb b/mmv1/third_party/terraform/go.mod.erb index db246d4dfd1a..544dd16ee673 100644 --- a/mmv1/third_party/terraform/go.mod.erb +++ b/mmv1/third_party/terraform/go.mod.erb @@ -26,8 +26,8 @@ require ( github.com/sirupsen/logrus v1.8.1 golang.org/x/net v0.14.0 golang.org/x/oauth2 v0.11.0 - google.golang.org/api v0.138.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 + google.golang.org/api v0.139.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 ) @@ -55,7 +55,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cpy v0.0.0-20211218193943-a9c933c06932 // indirect - github.com/google/s2a-go v0.1.5 // indirect + github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect diff --git a/mmv1/third_party/terraform/go.sum b/mmv1/third_party/terraform/go.sum index f1131ffa5f89..dab59d4c04e6 100644 --- a/mmv1/third_party/terraform/go.sum +++ b/mmv1/third_party/terraform/go.sum @@ -27,7 +27,6 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= @@ -41,18 +40,13 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creachadair/staticfile v0.1.2/go.mod h1:a3qySzCIXEprDGxk6tSxSI+dBBdLzqeBOMhZ+o2d3pM= @@ -67,8 +61,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -81,7 +73,6 @@ github.com/gammazero/deque v0.0.0-20180920172122-f6adf94963e4 h1:R+19WKQClnfMXS6 github.com/gammazero/deque v0.0.0-20180920172122-f6adf94963e4/go.mod h1:GeIq9qoE43YdGnDXURnmKTnGg15pQz4mYkXSTChbneI= github.com/gammazero/workerpool v0.0.0-20181230203049-86a96b5d5d92 h1:EipXK6U05IQ2wtuFRn4k3h0+2lXypzItoXGVyf4r9Io= github.com/gammazero/workerpool v0.0.0-20181230203049-86a96b5d5d92/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= @@ -116,10 +107,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -135,8 +124,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cpy v0.0.0-20211218193943-a9c933c06932 h1:5/4TSDzpDnHQ8rKEEQBjRlYx77mHOvXu08oGchxej7o= github.com/google/go-cpy v0.0.0-20211218193943-a9c933c06932/go.mod h1:cC6EdPbj/17GFCPDK39NRarlMI+kt+O60S12cNB5J9Y= -github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg= -github.com/google/s2a-go v0.1.5/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -146,7 +135,6 @@ github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56 github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= @@ -250,7 +238,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -265,7 +252,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -284,7 +270,6 @@ github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= @@ -293,7 +278,6 @@ github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeW github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -304,8 +288,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -314,7 +296,6 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -327,19 +308,15 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -348,7 +325,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -362,31 +338,23 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -397,15 +365,14 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.138.0 h1:K/tVp05MxNVbHShRw9m7e9VJGdagNeTdMzqPH7AUqr0= -google.golang.org/api v0.138.0/go.mod h1:4xyob8CxC+0GChNBvEUAk8VBKNvYOTWM9T3v3UfRxuY= +google.golang.org/api v0.139.0 h1:A1TrCPgMmOiYu0AiNkvQIpIx+D8blHTDcJ5EogkP7LI= +google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= @@ -414,23 +381,19 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44= google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -455,7 +418,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb index 211a8737b636..a7a2508a8da9 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb @@ -197,13 +197,11 @@ var schemaNodePool = map[string]*schema.Schema{ ForceNew: true, Description: `If set, refers to the name of a custom resource policy supplied by the user. The resource policy must be in the same project and region as the node pool. If not found, InvalidArgument error is returned.`, }, -<% unless version == 'ga' -%> "tpu_topology": { Type: schema.TypeString, Optional: true, Description: `TPU placement topology for pod slice node pool. https://cloud.google.com/tpu/docs/types-topologies#tpu_topologies`, }, -<% end -%> }, }, }, @@ -948,9 +946,7 @@ func expandNodePool(d *schema.ResourceData, prefix string) (*container.NodePool, np.PlacementPolicy = &container.PlacementPolicy{ Type: placement_policy["type"].(string), PolicyName: placement_policy["policy_name"].(string), -<% unless version == 'ga' -%> TpuTopology: placement_policy["tpu_topology"].(string), -<% end -%> } } } @@ -1143,9 +1139,7 @@ func flattenNodePool(d *schema.ResourceData, config *transport_tpg.Config, np *c { "type": np.PlacementPolicy.Type, "policy_name": np.PlacementPolicy.PolicyName, -<% unless version == 'ga' -%> "tpu_topology": np.PlacementPolicy.TpuTopology, -<% end -%> }, } } diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb index e5fc654afaf9..584e1c0867ee 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb @@ -3387,11 +3387,10 @@ resource "google_container_node_pool" "np" { `, clusterName, np) } -<% unless version == 'ga' -%> func TestAccContainerNodePool_tpuTopology(t *testing.T) { t.Parallel() - acctest.SkipIfVcr(t) - + t.Skip("https://github.com/hashicorp/terraform-provider-google/issues/15254#issuecomment-1646277473") + cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10)) np1 := fmt.Sprintf("tf-test-nodepool-%s", acctest.RandString(t, 10)) np2 := fmt.Sprintf("tf-test-nodepool-%s", acctest.RandString(t, 10)) @@ -3457,6 +3456,7 @@ resource "google_container_node_pool" "with_tpu_topology" { `, cluster, np1, np2, tpuTopology) } +<% unless version == 'ga' -%> func TestAccContainerNodePool_withHostMaintenancePolicy(t *testing.T) { t.Parallel() diff --git a/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown index 3f08b2c1dd89..523d2684a41f 100644 --- a/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown @@ -273,7 +273,7 @@ cluster. The resource policy must be in the same project and region as the node pool. If not found, InvalidArgument error is returned. -* `tpu_topology` - (Optional, Beta) The [TPU placement topology](https://cloud.google.com/tpu/docs/types-topologies#tpu_topologies) for pod slice node pool. +* `tpu_topology` - (Optional) The [TPU placement topology](https://cloud.google.com/tpu/docs/types-topologies#tpu_topologies) for pod slice node pool. ## Attributes Reference From 371716f739af1a3b59e5c7a0a345ede2a7fa5bcf Mon Sep 17 00:00:00 2001 From: Yanwei Guo Date: Fri, 15 Sep 2023 12:58:11 -0700 Subject: [PATCH 089/476] Adds Direct VPC egress support for Cloud Run V2 resources (#8932) --- mmv1/products/cloudrunv2/Job.yaml | 33 +++++++ mmv1/products/cloudrunv2/Service.yaml | 34 +++++++ .../examples/cloudrunv2_job_directvpc.tf.erb | 26 +++++ .../cloudrunv2_service_directvpc.tf.erb | 18 ++++ .../resource_cloud_run_v2_job_test.go | 94 +++++++++++++++++++ .../resource_cloud_run_v2_service_test.go | 76 +++++++++++++++ 6 files changed, 281 insertions(+) create mode 100644 mmv1/templates/terraform/examples/cloudrunv2_job_directvpc.tf.erb create mode 100644 mmv1/templates/terraform/examples/cloudrunv2_service_directvpc.tf.erb diff --git a/mmv1/products/cloudrunv2/Job.yaml b/mmv1/products/cloudrunv2/Job.yaml index d484d5e717c6..64fe831df7e9 100644 --- a/mmv1/products/cloudrunv2/Job.yaml +++ b/mmv1/products/cloudrunv2/Job.yaml @@ -84,6 +84,13 @@ examples: vpc_access_connector_name: 'run-vpc' vpc_compute_subnetwork_name: 'run-subnetwork' compute_network_name: 'run-network' + - !ruby/object:Provider::Terraform::Examples + name: 'cloudrunv2_job_directvpc' + primary_resource_id: 'default' + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-job%s\", context[\"random_suffix\"\ + ])" + vars: + cloud_run_job_name: 'cloudrun-job' - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_job_secret' primary_resource_id: 'default' @@ -645,6 +652,32 @@ properties: values: - :ALL_TRAFFIC - :PRIVATE_RANGES_ONLY + default_from_api: true + - !ruby/object:Api::Type::Array + name: 'networkInterfaces' + description: |- + Direct VPC egress settings. Currently only single network interface is supported. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'network' + description: |- + The VPC network that the Cloud Run resource will be able to send traffic to. At least one of network or subnetwork must be specified. If both + network and subnetwork are specified, the given VPC subnetwork must belong to the given VPC network. If network is not specified, it will be + looked up from the subnetwork. + default_from_api: true + - !ruby/object:Api::Type::String + name: 'subnetwork' + description: |- + The VPC subnetwork that the Cloud Run resource will get IPs from. At least one of network or subnetwork must be specified. If both + network and subnetwork are specified, the given VPC subnetwork must belong to the given VPC network. If subnetwork is not specified, the + subnetwork with the same name with the network will be used. + default_from_api: true + - !ruby/object:Api::Type::Array + name: 'tags' + description: |- + Network tags applied to this Cloud Run job. + item_type: Api::Type::String - !ruby/object:Api::Type::Integer name: 'maxRetries' description: |- diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index ae586f92dabe..e51b29c9d7e2 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -87,6 +87,14 @@ examples: vpc_access_connector_name: 'run-vpc' vpc_compute_subnetwork_name: 'run-subnetwork' compute_network_name: 'run-network' + - !ruby/object:Provider::Terraform::Examples + name: 'cloudrunv2_service_directvpc' + primary_resource_id: 'default' + primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", + context[\"random_suffix\"\ + ])" + vars: + cloud_run_service_name: 'cloudrun-service' - !ruby/object:Provider::Terraform::Examples name: 'cloudrunv2_service_probes' primary_resource_id: 'default' @@ -301,6 +309,32 @@ properties: values: - :ALL_TRAFFIC - :PRIVATE_RANGES_ONLY + default_from_api: true + - !ruby/object:Api::Type::Array + name: 'networkInterfaces' + description: |- + Direct VPC egress settings. Currently only single network interface is supported. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'network' + description: |- + The VPC network that the Cloud Run resource will be able to send traffic to. At least one of network or subnetwork must be specified. If both + network and subnetwork are specified, the given VPC subnetwork must belong to the given VPC network. If network is not specified, it will be + looked up from the subnetwork. + default_from_api: true + - !ruby/object:Api::Type::String + name: 'subnetwork' + description: |- + The VPC subnetwork that the Cloud Run resource will get IPs from. At least one of network or subnetwork must be specified. If both + network and subnetwork are specified, the given VPC subnetwork must belong to the given VPC network. If subnetwork is not specified, the + subnetwork with the same name with the network will be used. + default_from_api: true + - !ruby/object:Api::Type::Array + name: 'tags' + description: |- + Network tags applied to this Cloud Run service. + item_type: Api::Type::String - !ruby/object:Api::Type::String name: 'timeout' description: |- diff --git a/mmv1/templates/terraform/examples/cloudrunv2_job_directvpc.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_job_directvpc.tf.erb new file mode 100644 index 000000000000..a28913e7fc13 --- /dev/null +++ b/mmv1/templates/terraform/examples/cloudrunv2_job_directvpc.tf.erb @@ -0,0 +1,26 @@ +resource "google_cloud_run_v2_job" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['cloud_run_job_name'] %>" + location = "us-central1" + launch_stage = "BETA" + template { + template{ + containers { + image = "us-docker.pkg.dev/cloudrun/container/job" + } + vpc_access { + network_interfaces { + network = "default" + subnetwork = "default" + tags = ["tag1", "tag2", "tag3"] + } + egress = "ALL_TRAFFIC" + } + } + } + + lifecycle { + ignore_changes = [ + launch_stage, + ] + } +} diff --git a/mmv1/templates/terraform/examples/cloudrunv2_service_directvpc.tf.erb b/mmv1/templates/terraform/examples/cloudrunv2_service_directvpc.tf.erb new file mode 100644 index 000000000000..626c979b98d7 --- /dev/null +++ b/mmv1/templates/terraform/examples/cloudrunv2_service_directvpc.tf.erb @@ -0,0 +1,18 @@ +resource "google_cloud_run_v2_service" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['cloud_run_service_name'] %>" + location = "us-central1" + launch_stage = "BETA" + template { + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello" + } + vpc_access{ + network_interfaces { + network = "default" + subnetwork = "default" + tags = ["tag1", "tag2", "tag3"] + } + egress = "ALL_TRAFFIC" + } + } +} diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go index a874e89e16ff..6b35cff4101e 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go @@ -1,6 +1,7 @@ package cloudrunv2_test import ( + "fmt" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -204,3 +205,96 @@ resource "google_compute_network" "custom_test" { } `, context) } + +func TestAccCloudRunV2Job_cloudrunv2JobWithDirectVPCUpdate(t *testing.T) { + t.Parallel() + + jobName := fmt.Sprintf("tf-test-cloudrun-service%s", acctest.RandString(t, 10)) + context := map[string]interface{}{ + "job_name": jobName, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckCloudRunV2JobDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudRunV2Job_cloudrunv2JobWithDirectVPC(context), + }, + { + ResourceName: "google_cloud_run_v2_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "launch_stage"}, + }, + { + Config: testAccCloudRunV2Job_cloudrunv2JobWithDirectVPCUpdate(context), + }, + { + ResourceName: "google_cloud_run_v2_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "launch_stage"}, + }, + }, + }) +} + +func testAccCloudRunV2Job_cloudrunv2JobWithDirectVPC(context map[string]interface{}) string { + return acctest.Nprintf(` + resource "google_cloud_run_v2_job" "default" { + name = "%{job_name}" + location = "us-central1" + launch_stage = "BETA" + template { + template { + containers { + image = "us-docker.pkg.dev/cloudrun/container/job" + } + vpc_access { + network_interfaces { + network = "default" + } + } + } + } + + lifecycle { + ignore_changes = [ + launch_stage, + ] + } + } +`, context) +} + +func testAccCloudRunV2Job_cloudrunv2JobWithDirectVPCUpdate(context map[string]interface{}) string { + return acctest.Nprintf(` + resource "google_cloud_run_v2_job" "default" { + name = "%{job_name}" + location = "us-central1" + launch_stage = "BETA" + template { + template { + containers { + image = "us-docker.pkg.dev/cloudrun/container/job" + } + vpc_access { + network_interfaces { + network = "my-network" + subnetwork = "my-network" + tags = ["tag1", "tag2", "tag3"] + } + } + } + } + + lifecycle { + ignore_changes = [ + launch_stage, + ] + } + } +`, context) +} diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go index 00ddd0472239..803446aaf7ba 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go @@ -590,3 +590,79 @@ resource "google_cloud_run_v2_service" "default" { } `, context) } + +func TestAccCloudRunV2Service_cloudrunv2ServiceWithDirectVPCUpdate(t *testing.T) { + t.Parallel() + + serviceName := fmt.Sprintf("tf-test-cloudrun-service%s", acctest.RandString(t, 10)) + context := map[string]interface{}{ + "service_name": serviceName, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckCloudRunV2ServiceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudRunV2Service_cloudRunServiceWithDirectVPC(context), + }, + { + ResourceName: "google_cloud_run_v2_service.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location"}, + }, + { + Config: testAccCloudRunV2Service_cloudRunServiceWithDirectVPCUpdate(context), + }, + { + ResourceName: "google_cloud_run_v2_service.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location"}, + }, + }, + }) +} + +func testAccCloudRunV2Service_cloudRunServiceWithDirectVPC(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_cloud_run_v2_service" "default" { + name = "%{service_name}" + location = "us-central1" + launch_stage = "BETA" + template { + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello" + } + vpc_access { + network_interfaces { + network = "default" + } + } + } +} +`, context) +} + +func testAccCloudRunV2Service_cloudRunServiceWithDirectVPCUpdate(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_cloud_run_v2_service" "default" { + name = "%{service_name}" + location = "us-central1" + launch_stage = "BETA" + template { + containers { + image = "us-docker.pkg.dev/cloudrun/container/hello" + } + vpc_access { + network_interfaces { + subnetwork = "default" + tags = ["foo", "bar"] + } + } + } +} +`, context) +} From 452bdf6c42d60138ac5fe507900feb68637a40dd Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Fri, 15 Sep 2023 13:31:42 -0700 Subject: [PATCH 090/476] Add billing account to SQL PSC tests (#8973) --- .../resource_sql_database_instance_test.go | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go index 7f43e53d8870..326f858fcb2a 100644 --- a/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go +++ b/mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go @@ -790,6 +790,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(t instanceName := "tf-test-" + acctest.RandString(t, 10) projectId := "psctestproject" + acctest.RandString(t, 10) orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -797,7 +798,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(t CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), Check: resource.ComposeTestCheckFunc(verifyPscOperation("google_sql_database_instance.instance", true, true, nil)), }, { @@ -817,6 +818,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withEmptyAllowedConsumerProjects( instanceName := "tf-test-" + acctest.RandString(t, 10) projectId := "psctestproject" + acctest.RandString(t, 10) orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -824,7 +826,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withEmptyAllowedConsumerProjects( CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withEmptyAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withEmptyAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), Check: resource.ComposeTestCheckFunc(verifyPscOperation("google_sql_database_instance.instance", true, true, []string{})), }, { @@ -844,6 +846,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(t *te instanceName := "tf-test-" + acctest.RandString(t, 10) projectId := "psctestproject" + acctest.RandString(t, 10) orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -851,7 +854,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(t *te CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), Check: resource.ComposeTestCheckFunc(verifyPscOperation("google_sql_database_instance.instance", true, true, []string{envvar.GetTestProjectFromEnv()})), }, { @@ -871,6 +874,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_thenAddAllowedConsumerProjects_th instanceName := "tf-test-" + acctest.RandString(t, 10) projectId := "psctestproject" + acctest.RandString(t, 10) orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -878,7 +882,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_thenAddAllowedConsumerProjects_th CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), Check: resource.ComposeTestCheckFunc(verifyPscOperation("google_sql_database_instance.instance", true, true, nil)), }, { @@ -889,7 +893,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_thenAddAllowedConsumerProjects_th ImportStateVerifyIgnore: []string{"deletion_protection"}, }, { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), Check: resource.ComposeTestCheckFunc(verifyPscOperation("google_sql_database_instance.instance", true, true, []string{envvar.GetTestProjectFromEnv()})), }, { @@ -900,7 +904,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_thenAddAllowedConsumerProjects_th ImportStateVerifyIgnore: []string{"deletion_protection"}, }, { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), Check: resource.ComposeTestCheckFunc(verifyPscOperation("google_sql_database_instance.instance", true, true, []string{})), }, { @@ -920,6 +924,7 @@ func TestAccSqlDatabaseInstance_basicInstance_thenPSCEnabled(t *testing.T) { instanceName := "tf-test-" + acctest.RandString(t, 10) projectId := "psctestproject" + acctest.RandString(t, 10) orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -927,7 +932,7 @@ func TestAccSqlDatabaseInstance_basicInstance_thenPSCEnabled(t *testing.T) { CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccSqlDatabaseInstance_basicInstanceForPsc(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_basicInstanceForPsc(instanceName, projectId, orgId, billingAccount), }, { ResourceName: "google_sql_database_instance.instance", @@ -937,7 +942,7 @@ func TestAccSqlDatabaseInstance_basicInstance_thenPSCEnabled(t *testing.T) { ImportStateVerifyIgnore: []string{"deletion_protection"}, }, { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName, projectId, orgId, billingAccount), ExpectError: regexp.MustCompile("PSC connectivity can not be enabled"), }, }, @@ -950,6 +955,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withIpV4Enabled(t *testing.T) { instanceName := "tf-test-" + acctest.RandString(t, 10) projectId := "psctestproject" + acctest.RandString(t, 10) orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) acctest.VcrTest(t, resource.TestCase{ PreCheck: func() { acctest.AccTestPreCheck(t) }, @@ -957,7 +963,7 @@ func TestAccSqlDatabaseInstance_withPSCEnabled_withIpV4Enabled(t *testing.T) { CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccSqlDatabaseInstance_withPSCEnabled_withIpV4Enable(instanceName, projectId, orgId), + Config: testAccSqlDatabaseInstance_withPSCEnabled_withIpV4Enable(instanceName, projectId, orgId, billingAccount), ExpectError: regexp.MustCompile("PSC connectivity cannot be enabled together with public IP"), }, }, @@ -2572,12 +2578,13 @@ resource "google_sql_database_instance" "instance-failover" { `, instanceName, failoverName) } -func testAccSqlDatabaseInstance_basicInstanceForPsc(instanceName string, projectId string, orgId string) string { +func testAccSqlDatabaseInstance_basicInstanceForPsc(instanceName string, projectId string, orgId string, billingAccount string) string { return fmt.Sprintf(` resource "google_project" "testproject" { name = "%s" project_id = "%s" org_id = "%s" + billing_account = "%s" } resource "google_sql_database_instance" "instance" { @@ -2595,15 +2602,16 @@ resource "google_sql_database_instance" "instance" { availability_type = "REGIONAL" } } -`, projectId, projectId, orgId, instanceName) +`, projectId, projectId, orgId, billingAccount, instanceName) } -func testAccSqlDatabaseInstance_withPSCEnabled_withIpV4Enable(instanceName string, projectId string, orgId string) string { +func testAccSqlDatabaseInstance_withPSCEnabled_withIpV4Enable(instanceName string, projectId string, orgId string, billingAccount string) string { return fmt.Sprintf(` resource "google_project" "testproject" { name = "%s" project_id = "%s" org_id = "%s" + billing_account = "%s" } resource "google_sql_database_instance" "instance" { @@ -2627,15 +2635,16 @@ resource "google_sql_database_instance" "instance" { availability_type = "REGIONAL" } } -`, projectId, projectId, orgId, instanceName) +`, projectId, projectId, orgId, billingAccount, instanceName) } -func testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName string, projectId string, orgId string) string { +func testAccSqlDatabaseInstance_withPSCEnabled_withoutAllowedConsumerProjects(instanceName string, projectId string, orgId string, billingAccount string) string { return fmt.Sprintf(` resource "google_project" "testproject" { name = "%s" project_id = "%s" org_id = "%s" + billing_account = "%s" } resource "google_sql_database_instance" "instance" { @@ -2659,15 +2668,16 @@ resource "google_sql_database_instance" "instance" { availability_type = "REGIONAL" } } -`, projectId, projectId, orgId, instanceName) +`, projectId, projectId, orgId, billingAccount, instanceName) } -func testAccSqlDatabaseInstance_withPSCEnabled_withEmptyAllowedConsumerProjects(instanceName string, projectId string, orgId string) string { +func testAccSqlDatabaseInstance_withPSCEnabled_withEmptyAllowedConsumerProjects(instanceName string, projectId string, orgId string, billingAccount string) string { return fmt.Sprintf(` resource "google_project" "testproject" { name = "%s" project_id = "%s" org_id = "%s" + billing_account = "%s" } resource "google_sql_database_instance" "instance" { @@ -2692,16 +2702,18 @@ resource "google_sql_database_instance" "instance" { availability_type = "REGIONAL" } } -`, projectId, projectId, orgId, instanceName) +`, projectId, projectId, orgId, billingAccount, instanceName) } -func testAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(instanceName string, projectId string, orgId string) string { +func testAccSqlDatabaseInstance_withPSCEnabled_withAllowedConsumerProjects(instanceName string, projectId string, orgId string, billingAccount string) string { return fmt.Sprintf(` resource "google_project" "testproject" { name = "%s" project_id = "%s" org_id = "%s" + billing_account = "%s" } + resource "google_sql_database_instance" "instance" { project = google_project.testproject.project_id name = "%s" @@ -2724,7 +2736,7 @@ resource "google_sql_database_instance" "instance" { availability_type = "REGIONAL" } } -`, projectId, projectId, orgId, instanceName, projectId) +`, projectId, projectId, orgId, billingAccount, instanceName, projectId) } func verifyPscOperation(resourceName string, isPscConfigExpected bool, expectedPscEnabled bool, expectedAllowedConsumerProjects []string) func(*terraform.State) error { From 6696d29c98e7a0d48735b4662b6ab80fb01d2130 Mon Sep 17 00:00:00 2001 From: ixsakra <34536530+rlia@users.noreply.github.com> Date: Sat, 16 Sep 2023 06:14:44 +0900 Subject: [PATCH 091/476] feat(google_container_node_pool): support fast socket (#8884) --- .../services/container/node_config.go.erb | 33 +++++++++ .../resource_container_node_pool.go.erb | 34 +++++++++ .../resource_container_node_pool_test.go.erb | 72 +++++++++++++++++++ .../docs/r/container_cluster.html.markdown | 8 +++ 4 files changed, 147 insertions(+) diff --git a/mmv1/third_party/terraform/services/container/node_config.go.erb b/mmv1/third_party/terraform/services/container/node_config.go.erb index d331c4205b0b..8db029040fad 100644 --- a/mmv1/third_party/terraform/services/container/node_config.go.erb +++ b/mmv1/third_party/terraform/services/container/node_config.go.erb @@ -642,6 +642,21 @@ func schemaNodeConfig() *schema.Schema { }, }, }, + "fast_socket": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: `Enable or disable NCCL Fast Socket in the node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `Whether or not NCCL Fast Socket is enabled`, + }, + }, + }, + }, }, }, } @@ -779,6 +794,13 @@ func expandNodeConfig(v interface{}) *container.NodeConfig { } } + if v, ok := nodeConfig["fast_socket"]; ok && len(v.([]interface{})) > 0 { + conf := v.([]interface{})[0].(map[string]interface{}) + nc.FastSocket = &container.FastSocket{ + Enabled: conf["enabled"].(bool), + } + } + if v, ok := nodeConfig["reservation_affinity"]; ok && len(v.([]interface{})) > 0 { conf := v.([]interface{})[0].(map[string]interface{}) valuesSet := conf["values"].(*schema.Set) @@ -1120,6 +1142,7 @@ func flattenNodeConfig(c *container.NodeConfig) []map[string]interface{} { "node_group": c.NodeGroup, "advanced_machine_features": flattenAdvancedMachineFeaturesConfig(c.AdvancedMachineFeatures), "sole_tenant_config": flattenSoleTenantConfig(c.SoleTenantConfig), + "fast_socket": flattenFastSocket(c.FastSocket), }) if len(c.OauthScopes) > 0 { @@ -1450,6 +1473,16 @@ func flattenSoleTenantConfig(c *container.SoleTenantConfig) []map[string]interfa }) } +func flattenFastSocket(c *container.FastSocket) []map[string]interface{} { + result := []map[string]interface{}{} + if c != nil { + result = append(result, map[string]interface{}{ + "enabled": c.Enabled, + }) + } + return result +} + <% unless version == 'ga' -%> func flattenHostMaintenancePolicy(c *container.HostMaintenancePolicy) []map[string]interface{} { result := []map[string]interface{}{} diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb index a7a2508a8da9..f308ffa2b5b3 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb @@ -1646,7 +1646,41 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node log.Printf("[INFO] Updated linux_node_config for node pool %s", name) } + if d.HasChange(prefix + "node_config.0.fast_socket") { + req := &container.UpdateNodePoolRequest{ + NodePoolId: name, + FastSocket: &container.FastSocket{}, + } + if v, ok := d.GetOk(prefix + "node_config.0.fast_socket"); ok { + fastSocket := v.([]interface{})[0].(map[string]interface{}) + req.FastSocket = &container.FastSocket{ + Enabled: fastSocket["enabled"].(bool), + } + } + updateF := func() error { + clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(name),req) + if config.UserProjectOverride { + clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project) + } + op, err := clusterNodePoolsUpdateCall.Do() + if err != nil { + return err + } + + // Wait until it's updated + return ContainerOperationWait(config, op, + nodePoolInfo.project, + nodePoolInfo.location, + "updating GKE node pool fast_socket", userAgent, + timeout) + } + + if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + return err + } + log.Printf("[INFO] Updated fast_socket for node pool %s", name) + } } if d.HasChange(prefix + "node_count") { diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb index 584e1c0867ee..0fb6f5ede53a 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.erb @@ -1511,6 +1511,78 @@ resource "google_container_node_pool" "np" { `, cluster, np) } +func TestAccContainerNodePool_fastSocket(t *testing.T) { + t.Parallel() + + cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10)) + np := fmt.Sprintf("tf-test-nodepool-%s", acctest.RandString(t, 10)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckContainerNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccContainerNodePool_fastSocket(cluster, np, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_container_node_pool.np", + "node_config.0.fast_socket.0.enabled", "true"), + ), + }, + { + ResourceName: "google_container_node_pool.np", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccContainerNodePool_fastSocket(cluster, np, false), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_container_node_pool.np", + "node_config.0.fast_socket.0.enabled", "false"), + ), + }, + { + ResourceName: "google_container_node_pool.np", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccContainerNodePool_fastSocket(cluster, np string, enabled bool) string { + return fmt.Sprintf(` +resource "google_container_cluster" "cluster" { + name = "%s" + location = "us-central1-f" + initial_node_count = 1 + min_master_version = "1.25" +} + +resource "google_container_node_pool" "np" { + name = "%s" + location = "us-central1-f" + cluster = google_container_cluster.cluster.name + initial_node_count = 1 + + node_config { + machine_type = "n1-standard-8" + image_type = "COS_CONTAINERD" + guest_accelerator { + type = "nvidia-tesla-p100" + count = 1 + } + gvnic { + enabled = true + } + fast_socket { + enabled = %t + } + } +} +`, cluster, np, enabled) +} + func TestAccContainerNodePool_compactPlacement(t *testing.T) { t.Parallel() diff --git a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown index e5eb29fe4011..3a12ce9213ea 100644 --- a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -795,6 +795,10 @@ ephemeral_storage_local_ssd_config { local_ssd_count = 2 } ``` +* `fast_socket` - (Optional) Parameters for the NCCL Fast Socket feature. If unspecified, NCCL Fast Socket will not be enabled on the node pool. + Node Pool must enable gvnic. + GKE version 1.25.2-gke.1700 or later. + Structure is [documented below](#nested_fast_socket). * `local_nvme_ssd_block_config` - (Optional) Parameters for the local NVMe SSDs. Structure is [documented below](#nested_local_nvme_ssd_block_config). @@ -965,6 +969,10 @@ sole_tenant_config { * `local_ssd_count` (Required) - Number of local SSDs to use to back ephemeral storage. Uses NVMe interfaces. Each local SSD is 375 GB in size. If zero, it means to disable using local SSDs as ephemeral storage. +The `fast_socket` block supports: + +* `enabled` (Required) - Whether or not the NCCL Fast Socket is enabled + The `local_nvme_ssd_block_config` block supports: * `local_ssd_count` (Required) - Number of raw-block local NVMe SSD disks to be attached to the node. Each local SSD is 375 GB in size. If zero, it means no raw-block local NVMe SSD disks to be attached to the node. From 7d9dc66236d53cd40cb28d6c73dcefe9b1bf8310 Mon Sep 17 00:00:00 2001 From: wj-chen Date: Fri, 15 Sep 2023 14:50:58 -0700 Subject: [PATCH 092/476] Update documentation for google_bigquery_table.time_partitioning.expiration_ms (#8827) --- mmv1/products/bigquery/Table.yaml | 5 ++++- .../terraform/services/bigquery/resource_bigquery_table.go | 7 +++++-- .../services/bigquery/resource_bigquery_table_test.go | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/mmv1/products/bigquery/Table.yaml b/mmv1/products/bigquery/Table.yaml index ae9c5bb81666..5b0d92ec3f9b 100644 --- a/mmv1/products/bigquery/Table.yaml +++ b/mmv1/products/bigquery/Table.yaml @@ -175,7 +175,10 @@ properties: name: 'expirationMs' description: | Number of milliseconds for which to keep the storage for a - partition. + partition. If unspecified when the table is created in a dataset + that has `defaultPartitionExpirationMs`, it will inherit + the value of `defaultPartitionExpirationMs` from the dataset. + To specify a unlimited expiration, set the value to 0. - !ruby/object:Api::Type::String name: 'field' description: | diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go index f32333ec90b4..e8568fea396d 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table.go @@ -865,8 +865,11 @@ func ResourceBigQueryTable() *schema.Resource { Description: `If specified, configures time-based partitioning for this table.`, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - // ExpirationMs: [Optional] Number of milliseconds for which to keep the - // storage for a partition. + // ExpirationMs: [Optional] Number of milliseconds for which to keep the storage for a + // partition. If unspecified when the table is created in a dataset that has + // `defaultPartitionExpirationMs`, it will inherit the value of + // `defaultPartitionExpirationMs` from the dataset. + // To specify a unlimited expiration, set the value to 0. "expiration_ms": { Type: schema.TypeInt, Optional: true, diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go index 8c6e63d11931..46a7224eb043 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go @@ -1441,6 +1441,7 @@ resource "google_bigquery_table" "test" { type = "%s" field = "ts" require_partition_filter = true + expiration_ms = 1000 } clustering = ["some_int", "some_string"] schema = < Date: Fri, 15 Sep 2023 15:02:09 -0700 Subject: [PATCH 093/476] fix `google_container_node_pool` (#8976) --- .../services/container/resource_container_node_pool.go.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb index f308ffa2b5b3..1eca550efe8c 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.erb @@ -1675,7 +1675,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node timeout) } - if err := tpgresource.RetryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { + if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil { return err } From b8279d996a5fb755bd3bb42ed7fb2a874de52778 Mon Sep 17 00:00:00 2001 From: Riley Zhou <35350176+RileyHYZ@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:16:00 -0400 Subject: [PATCH 094/476] Clean up eventarc test (#8975) * Clean up eventarc handwritten tests * update indentation --- .../resource_eventarc_trigger_test.go.erb | 23 +++++----- .../samples/trigger/basic_update_json.tf.tmpl | 46 ------------------- .../trigger/basic_update_proto.tf.tmpl | 46 ------------------- 3 files changed, 12 insertions(+), 103 deletions(-) delete mode 100644 tpgtools/overrides/eventarc/samples/trigger/basic_update_json.tf.tmpl delete mode 100644 tpgtools/overrides/eventarc/samples/trigger/basic_update_proto.tf.tmpl diff --git a/mmv1/third_party/terraform/services/eventarc/resource_eventarc_trigger_test.go.erb b/mmv1/third_party/terraform/services/eventarc/resource_eventarc_trigger_test.go.erb index b5aabe2cba4a..bff74bdd841a 100644 --- a/mmv1/third_party/terraform/services/eventarc/resource_eventarc_trigger_test.go.erb +++ b/mmv1/third_party/terraform/services/eventarc/resource_eventarc_trigger_test.go.erb @@ -125,11 +125,11 @@ resource "google_eventarc_trigger" "primary" { region = "%{region}" } } - service_account= "%{service_account}" + service_account = "%{service_account}" channel = "projects/${data.google_project.test_project.project_id}/locations/%{region}/channels/${google_eventarc_channel.test_channel.name}" - depends_on =[google_cloud_run_service.default,google_eventarc_channel.test_channel] + depends_on = [google_cloud_run_service.default,google_eventarc_channel.test_channel] } `, context) } @@ -152,15 +152,16 @@ func testAccCheckEventarcChannelTriggerDestroyProducer(t *testing.T) func(s *ter } obj := &eventarc.Trigger{ - Location: dcl.String(rs.Primary.Attributes["location"]), - Name: dcl.String(rs.Primary.Attributes["name"]), - Project: dcl.StringOrNil(rs.Primary.Attributes["project"]), - ServiceAccount: dcl.String(rs.Primary.Attributes["service_account"]), - CreateTime: dcl.StringOrNil(rs.Primary.Attributes["create_time"]), - Etag: dcl.StringOrNil(rs.Primary.Attributes["etag"]), - Uid: dcl.StringOrNil(rs.Primary.Attributes["uid"]), - UpdateTime: dcl.StringOrNil(rs.Primary.Attributes["update_time"]), - Channel: dcl.StringOrNil(rs.Primary.Attributes["channel"]), + Location: dcl.String(rs.Primary.Attributes["location"]), + Name: dcl.String(rs.Primary.Attributes["name"]), + Project: dcl.StringOrNil(rs.Primary.Attributes["project"]), + ServiceAccount: dcl.String(rs.Primary.Attributes["service_account"]), + CreateTime: dcl.StringOrNil(rs.Primary.Attributes["create_time"]), + Etag: dcl.StringOrNil(rs.Primary.Attributes["etag"]), + Uid: dcl.StringOrNil(rs.Primary.Attributes["uid"]), + UpdateTime: dcl.StringOrNil(rs.Primary.Attributes["update_time"]), + Channel: dcl.StringOrNil(rs.Primary.Attributes["channel"]), + EventDataContentType: dcl.StringOrNil(rs.Primary.Attributes["event_data_content_type"]), } client := transport_tpg.NewDCLEventarcClient(config, config.UserAgent, billingProject, 0) diff --git a/tpgtools/overrides/eventarc/samples/trigger/basic_update_json.tf.tmpl b/tpgtools/overrides/eventarc/samples/trigger/basic_update_json.tf.tmpl deleted file mode 100644 index de6ee2b9ae15..000000000000 --- a/tpgtools/overrides/eventarc/samples/trigger/basic_update_json.tf.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -resource "google_eventarc_trigger" "primary" { - name = "{{name}}" - location = "europe-west1" - matching_criteria { - attribute = "type" - value = "google.cloud.pubsub.topic.v1.messagePublished" - } - destination { - cloud_run_service { - service = google_cloud_run_service.default.name - region = "europe-west1" - } - } - event_data_content_type = "application/json" -} - -resource "google_pubsub_topic" "foo" { - name = "{{topic}}" -} - -resource "google_cloud_run_service" "default" { - name = "{{eventarc-service}}" - location = "europe-west1" - - metadata { - namespace = "{{project}}" - } - - template { - spec { - containers { - image = "gcr.io/cloudrun/hello" - ports { - container_port = 8080 - } - } - container_concurrency = 50 - timeout_seconds = 100 - } - } - - traffic { - percent = 100 - latest_revision = true - } -} diff --git a/tpgtools/overrides/eventarc/samples/trigger/basic_update_proto.tf.tmpl b/tpgtools/overrides/eventarc/samples/trigger/basic_update_proto.tf.tmpl deleted file mode 100644 index a8594608cd29..000000000000 --- a/tpgtools/overrides/eventarc/samples/trigger/basic_update_proto.tf.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -resource "google_eventarc_trigger" "primary" { - name = "{{name}}" - location = "europe-west1" - matching_criteria { - attribute = "type" - value = "google.cloud.pubsub.topic.v1.messagePublished" - } - destination { - cloud_run_service { - service = google_cloud_run_service.default.name - region = "europe-west1" - } - } - event_data_content_type = "application/proto" -} - -resource "google_pubsub_topic" "foo" { - name = "{{topic}}" -} - -resource "google_cloud_run_service" "default" { - name = "{{eventarc-service}}" - location = "europe-west1" - - metadata { - namespace = "{{project}}" - } - - template { - spec { - containers { - image = "gcr.io/cloudrun/hello" - ports { - container_port = 8080 - } - } - container_concurrency = 50 - timeout_seconds = 100 - } - } - - traffic { - percent = 100 - latest_revision = true - } -} From 110956fc14ae187bc899bdf7871c8518f33c9ca8 Mon Sep 17 00:00:00 2001 From: Mohamed Fouad <110571142+mraouffouad@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:22:39 -0400 Subject: [PATCH 095/476] Move sign_in from google_identity_platform_project_default_config to google_identity_platform_config. (#8559) Co-authored-by: Shuya Ma <87669292+shuyama1@users.noreply.github.com> --- mmv1/products/identityplatform/Config.yaml | 82 +++++++++++ .../ProjectDefaultConfig.yaml | 1 + .../identity_platform_config_anonymous.go | 16 +++ .../identity_platform_config_basic.tf.erb | 18 ++- ..._project_default_config_deprecation.go.erb | 17 +++ .../resource_identity_platform_config_test.go | 127 ++++++++++++++++++ .../guides/version_5_upgrade.html.markdown | 6 + 7 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 mmv1/templates/terraform/custom_flatten/identity_platform_config_anonymous.go create mode 100644 mmv1/templates/terraform/resource_definition/identity_platform_project_default_config_deprecation.go.erb create mode 100644 mmv1/third_party/terraform/services/identityplatform/resource_identity_platform_config_test.go diff --git a/mmv1/products/identityplatform/Config.yaml b/mmv1/products/identityplatform/Config.yaml index 04c5f6fcf538..55a2c57347b0 100644 --- a/mmv1/products/identityplatform/Config.yaml +++ b/mmv1/products/identityplatform/Config.yaml @@ -73,6 +73,88 @@ properties: name: 'autodeleteAnonymousUsers' description: | Whether anonymous users will be auto-deleted after a period of 30 days + - !ruby/object:Api::Type::NestedObject + name: 'signIn' + description: | + Configuration related to local sign in methods. + properties: + - !ruby/object:Api::Type::NestedObject + name: email + description: | + Configuration options related to authenticating a user by their email address. + properties: + - !ruby/object:Api::Type::Boolean + name: enabled + required: true + description: | + Whether email auth is enabled for the project or not. + - !ruby/object:Api::Type::Boolean + name: 'passwordRequired' + description: | + Whether a password is required for email auth or not. If true, both an email and + password must be provided to sign in. If false, a user may sign in via either + email/password or email link. + - !ruby/object:Api::Type::NestedObject + name: phoneNumber + description: | + Configuration options related to authenticated a user by their phone number. + properties: + - !ruby/object:Api::Type::Boolean + name: enabled + required: true + description: | + Whether phone number auth is enabled for the project or not. + - !ruby/object:Api::Type::KeyValuePairs + name: 'testPhoneNumbers' + description: | + A map of that can be used for phone auth testing. + - !ruby/object:Api::Type::NestedObject + name: anonymous + custom_flatten: 'templates/terraform/custom_flatten/identity_platform_config_anonymous.go' + description: | + Configuration options related to authenticating an anonymous user. + properties: + - !ruby/object:Api::Type::Boolean + name: enabled + required: true + send_empty_value: true + description: | + Whether anonymous user auth is enabled for the project or not. + - !ruby/object:Api::Type::Boolean + name: allowDuplicateEmails + description: | + Whether to allow more than one account to have the same email. + - !ruby/object:Api::Type::NestedObject + name: hashConfig + output: true + description: | + Output only. Hash config information. + properties: + - !ruby/object:Api::Type::String + name: algorithm + output: true + description: | + Different password hash algorithms used in Identity Toolkit. + - !ruby/object:Api::Type::String + name: 'signerKey' + output: true + description: | + Signer key in base64. + - !ruby/object:Api::Type::String + name: 'saltSeparator' + output: true + description: | + Non-printable character to be inserted between the salt and plain text password in base64. + - !ruby/object:Api::Type::Integer + name: rounds + output: true + description: | + How many rounds for hash calculation. Used by scrypt and other similar password derivation algorithms. + - !ruby/object:Api::Type::Integer + name: 'memoryCost' + output: true + description: | + Memory cost for hash calculation. Used by scrypt and other similar password derivation algorithms. See https://tools.ietf.org/html/rfc7914 for explanation of field. - !ruby/object:Api::Type::NestedObject name: 'blockingFunctions' description: | diff --git a/mmv1/products/identityplatform/ProjectDefaultConfig.yaml b/mmv1/products/identityplatform/ProjectDefaultConfig.yaml index 738d8518ff03..908d324f94c7 100644 --- a/mmv1/products/identityplatform/ProjectDefaultConfig.yaml +++ b/mmv1/products/identityplatform/ProjectDefaultConfig.yaml @@ -23,6 +23,7 @@ create_verb: :PATCH delete_verb: :PATCH custom_code: !ruby/object:Provider::Terraform::CustomCode test_check_destroy: templates/terraform/custom_check_destroy/identity_platform_project_default_config.go.erb + resource_definition: templates/terraform/resource_definition/identity_platform_project_default_config_deprecation.go.erb docs: !ruby/object:Provider::Terraform::Docs warning: | If you are using User ADCs (Application Default Credentials) with this resource, diff --git a/mmv1/templates/terraform/custom_flatten/identity_platform_config_anonymous.go b/mmv1/templates/terraform/custom_flatten/identity_platform_config_anonymous.go new file mode 100644 index 000000000000..5487fd8a8ba1 --- /dev/null +++ b/mmv1/templates/terraform/custom_flatten/identity_platform_config_anonymous.go @@ -0,0 +1,16 @@ +func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + + original := v.(map[string]interface{}) + transformed := make(map[string]interface{}) + + if original["enabled"] == nil { + transformed["enabled"] = false + } else { + transformed["enabled"] = original["enabled"] + } + + return []interface{}{transformed} +} diff --git a/mmv1/templates/terraform/examples/identity_platform_config_basic.tf.erb b/mmv1/templates/terraform/examples/identity_platform_config_basic.tf.erb index 9880802797c2..63cbf5d730ce 100644 --- a/mmv1/templates/terraform/examples/identity_platform_config_basic.tf.erb +++ b/mmv1/templates/terraform/examples/identity_platform_config_basic.tf.erb @@ -13,10 +13,26 @@ resource "google_project_service" "identitytoolkit" { service = "identitytoolkit.googleapis.com" } - resource "google_identity_platform_config" "default" { project = google_project.default.project_id autodelete_anonymous_users = true + sign_in { + allow_duplicate_emails = true + + anonymous { + enabled = true + } + email { + enabled = true + password_required = false + } + phone_number { + enabled = true + test_phone_numbers = { + "+11231231234" = "000000" + } + } + } blocking_functions { triggers { event_type = "beforeSignIn" diff --git a/mmv1/templates/terraform/resource_definition/identity_platform_project_default_config_deprecation.go.erb b/mmv1/templates/terraform/resource_definition/identity_platform_project_default_config_deprecation.go.erb new file mode 100644 index 000000000000..9bdf1b6ba8eb --- /dev/null +++ b/mmv1/templates/terraform/resource_definition/identity_platform_project_default_config_deprecation.go.erb @@ -0,0 +1,17 @@ +<%# The license inside this block applies to this file. + # 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. +-%> +DeprecationMessage: "Deprecated. Use the `google_identity_platform_config` resource instead. " + + "It contains a more comprehensive list of fields, and was created before " + + "`google_identity_platform_project_default_config` was added.", diff --git a/mmv1/third_party/terraform/services/identityplatform/resource_identity_platform_config_test.go b/mmv1/third_party/terraform/services/identityplatform/resource_identity_platform_config_test.go new file mode 100644 index 000000000000..dfdad0654af4 --- /dev/null +++ b/mmv1/third_party/terraform/services/identityplatform/resource_identity_platform_config_test.go @@ -0,0 +1,127 @@ +package identityplatform_test + +import ( + "testing" + "time" + + "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 TestAccIdentityPlatformConfig_update(t *testing.T) { + acctest.SkipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "org_id": envvar.GetTestOrgFromEnv(t), + "billing_acct": envvar.GetTestBillingAccountFromEnv(t), + "quota_start_time": time.Now().AddDate(0, 0, 1).Format(time.RFC3339), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformConfig_basic(context), + }, + { + ResourceName: "google_identity_platform_config.basic", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccIdentityPlatformConfig_update(context), + }, + { + ResourceName: "google_identity_platform_config.basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIdentityPlatformConfig_basic(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_project" "basic" { + project_id = "tf-test-my-project%{random_suffix}" + name = "tf-test-my-project%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_acct}" + labels = { + firebase = "enabled" + } +} + +resource "google_project_service" "identitytoolkit" { + project = google_project.basic.project_id + service = "identitytoolkit.googleapis.com" +} + +resource "google_identity_platform_config" "basic" { + project = google_project.basic.project_id + autodelete_anonymous_users = true + sign_in { + allow_duplicate_emails = true + + anonymous { + enabled = true + } + email { + enabled = true + password_required = false + } + phone_number { + enabled = true + test_phone_numbers = { + "+11231231234" = "000000" + } + } + } +} +`, context) +} + +func testAccIdentityPlatformConfig_update(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_project" "basic" { + project_id = "tf-test-my-project%{random_suffix}" + name = "tf-test-my-project%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_acct}" + labels = { + firebase = "enabled" + } +} + +resource "google_project_service" "identitytoolkit" { + project = google_project.basic.project_id + service = "identitytoolkit.googleapis.com" +} + +resource "google_identity_platform_config" "basic" { + project = google_project.basic.project_id + sign_in { + allow_duplicate_emails = false + + anonymous { + enabled = false + } + email { + enabled = true + password_required = true + } + phone_number { + enabled = true + test_phone_numbers = { + "+17651212343" = "111111" + } + } + } +} +`, context) +} diff --git a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown index 7264d81c38b1..ed27d4175f40 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_5_upgrade.html.markdown @@ -510,3 +510,9 @@ resource "google_secret_manager_secret" "my-secret" { } } ``` + +## Resource: `google_identity_platform_project_default_config` + +### `google_identity_platform_project_default_config` has been removed from the provider + +Use the `google_identity_platform_config` resource instead. It contains a more comprehensive list of fields, and was created before `google_identity_platform_project_default_config` was added. \ No newline at end of file From 0ef602f678611b77172a342e8e2980633054ed01 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Fri, 15 Sep 2023 16:05:37 -0700 Subject: [PATCH 096/476] Apply new labels model to more resources (part 1) (#8950) * Apply new labels model to more resources (part 1) * Handle labels field inside flatten object * Fix the tests for datasource * Fix typo * Fix typo --- mmv1/api/resource.rb | 41 ++++++++++++------- mmv1/api/type.rb | 5 ++- mmv1/products/activedirectory/Domain.yaml | 2 +- mmv1/products/activedirectory/Peering.yaml | 2 +- mmv1/products/alloydb/Backup.yaml | 2 +- mmv1/products/alloydb/Cluster.yaml | 2 +- mmv1/products/apigateway/ApiConfig.yaml | 2 +- mmv1/products/apigateway/ApiResource.yaml | 2 +- mmv1/products/apigateway/Gateway.yaml | 2 +- .../products/artifactregistry/Repository.yaml | 2 +- mmv1/products/beyondcorp/AppConnection.yaml | 2 +- mmv1/products/beyondcorp/AppConnector.yaml | 2 +- mmv1/products/beyondcorp/AppGateway.yaml | 2 +- mmv1/products/bigquery/Job.yaml | 2 +- mmv1/products/bigquery/Table.yaml | 2 +- .../certificatemanager/Certificate.yaml | 2 +- .../CertificateIssuanceConfig.yaml | 2 +- .../certificatemanager/CertificateMap.yaml | 3 +- .../CertificateMapEntry.yaml | 3 +- .../certificatemanager/DnsAuthorization.yaml | 2 +- .../certificatemanager/TrustConfig.yaml | 2 +- .../cloudfunctions/CloudFunction.yaml | 2 +- mmv1/products/cloudfunctions2/Function.yaml | 2 +- mmv1/products/cloudrunv2/Job.yaml | 2 +- mmv1/products/cloudrunv2/Service.yaml | 2 +- .../connectionprofile.yaml | 2 +- mmv1/products/datafusion/Instance.yaml | 2 +- mmv1/products/dataplex/Datascan.yaml | 2 +- mmv1/products/dataplex/Task.yaml | 2 +- .../datastream/ConnectionProfile.yaml | 2 +- .../datastream/PrivateConnection.yaml | 2 +- mmv1/products/datastream/Stream.yaml | 2 +- mmv1/provider/terraform.rb | 2 +- .../examples/base_configs/test_file.go.erb | 3 +- ...ager_google_managed_certificate_dns.tf.erb | 3 ++ .../terraform/expand_property_method.erb | 1 + .../terraform/acctest/test_utils.go.erb | 6 +++ ...rce_active_directory_domain_update_test.go | 6 +-- .../alloydb/resource_alloydb_backup_test.go | 6 +-- .../alloydb/resource_alloydb_cluster_test.go | 4 +- ...ource_artifact_registry_repository_test.go | 8 +++- ...e_artifact_registry_repository_test.go.erb | 2 + .../bigquery/resource_bigquery_job_test.go | 2 +- .../bigquery/resource_bigquery_table_test.go | 10 ++--- ...tificate_manager_dns_authorization_test.go | 4 +- ...e_certificate_manager_trust_config_test.go | 14 ++++--- ...source_cloudfunctions_function_test.go.erb | 10 ++--- ...ce_google_cloudfunctions2_function_test.go | 14 ++++++- .../resource_cloudfunctions2_function_test.go | 14 +++++-- .../resource_cloud_run_v2_job_test.go | 4 +- .../resource_cloud_run_v2_service_test.go | 4 +- ...gration_service_connection_profile_test.go | 4 +- .../resource_data_fusion_instance_test.go | 28 +++++++------ .../resource_datastream_stream_test.go | 8 ++-- 54 files changed, 157 insertions(+), 108 deletions(-) diff --git a/mmv1/api/resource.rb b/mmv1/api/resource.rb index a0ae098eaad7..cf4f9d45542b 100644 --- a/mmv1/api/resource.rb +++ b/mmv1/api/resource.rb @@ -460,7 +460,7 @@ def add_labels_related_fields(props, parent) elsif p.is_a? Api::Type::KeyValueAnnotations add_annotations_fields(props, parent, p) elsif (p.is_a? Api::Type::NestedObject) && !p.all_properties.nil? - p.properties = add_labels_related_fields(p.all_properties, p.name) + p.properties = add_labels_related_fields(p.all_properties, p) end end props @@ -471,16 +471,14 @@ def add_labels_fields(props, parent, labels) labels.ignore_write = true @custom_diff ||= [] - if parent.nil? + if parent.nil? || parent.flatten_object @custom_diff.append('tpgresource.SetLabelsDiff') - elsif parent == 'metadata' + elsif parent.name == 'metadata' @custom_diff.append('tpgresource.SetMetadataLabelsDiff') end props << build_terraform_labels_field('labels', labels.field_min_version) - props << build_effective_labels_field( - 'labels', labels.field_min_version, labels.update_verb, labels.update_url - ) + props << build_effective_labels_field('labels', labels) end def add_annotations_fields(props, parent, annotations) @@ -491,17 +489,14 @@ def add_annotations_fields(props, parent, annotations) @custom_diff ||= [] if parent.nil? @custom_diff.append('tpgresource.SetAnnotationsDiff') - elsif parent == 'metadata' + elsif parent.name == 'metadata' @custom_diff.append('tpgresource.SetMetadataAnnotationsDiff') end - props << build_effective_labels_field( - 'annotations', annotations.field_min_version, - annotations.update_verb, annotations.update_url - ) + props << build_effective_labels_field('annotations', annotations) end - def build_effective_labels_field(name, min_version, update_verb, update_url) + def build_effective_labels_field(name, labels) description = "All of #{name} (key/value pairs)\ present on the resource in GCP, including the #{name} configured through Terraform,\ other clients and services." @@ -511,9 +506,10 @@ def build_effective_labels_field(name, min_version, update_verb, update_url) output: true, api_name: name, description:, - min_version:, - update_verb:, - update_url: + min_version: labels.field_min_version, + update_verb: labels.update_verb, + update_url: labels.update_url, + immutable: labels.immutable ) end @@ -531,6 +527,21 @@ def build_terraform_labels_field(name, min_version) ) end + # Return labels fields that should be added to ImportStateVerifyIgnore + def ignore_read_labels_fields(props) + fields = [] + props.each do |p| + if (p.is_a? Api::Type::KeyValueLabels) || + (p.is_a? Api::Type::KeyValueTerraformLabels) || + (p.is_a? Api::Type::KeyValueAnnotations) + fields << p.terraform_lineage + elsif (p.is_a? Api::Type::NestedObject) && !p.all_properties.nil? + fields.concat(ignore_read_labels_fields(p.all_properties)) + end + end + fields + end + # ==================== # Version-related methods # ==================== diff --git a/mmv1/api/type.rb b/mmv1/api/type.rb index c9b385e6b4b6..0d81c8335929 100644 --- a/mmv1/api/type.rb +++ b/mmv1/api/type.rb @@ -269,7 +269,7 @@ def lineage # Prints the access path of the field in the configration eg: metadata.0.labels # The only intended purpose is to get the value of the labes field by calling d.Get(). def terraform_lineage - return name&.underscore if __parent.nil? + return name&.underscore if __parent.nil? || __parent.flatten_object "#{__parent.terraform_lineage}.0.#{name&.underscore}" end @@ -769,7 +769,7 @@ class KeyValuePairs < Composite attr_accessor :ignore_write def initialize(name: nil, output: nil, api_name: nil, description: nil, min_version: nil, - ignore_write: nil, update_verb: nil, update_url: nil) + ignore_write: nil, update_verb: nil, update_url: nil, immutable: nil) super() @name = name @@ -780,6 +780,7 @@ def initialize(name: nil, output: nil, api_name: nil, description: nil, min_vers @ignore_write = ignore_write @update_verb = update_verb @update_url = update_url + @immutable = immutable end def validate diff --git a/mmv1/products/activedirectory/Domain.yaml b/mmv1/products/activedirectory/Domain.yaml index 8b0cc3e78b33..7ca646ef3565 100644 --- a/mmv1/products/activedirectory/Domain.yaml +++ b/mmv1/products/activedirectory/Domain.yaml @@ -85,7 +85,7 @@ properties: description: 'The unique name of the domain using the format: `projects/{project}/locations/global/domains/{domainName}`.' - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'Resource labels that can contain user-provided metadata' - !ruby/object:Api::Type::Array diff --git a/mmv1/products/activedirectory/Peering.yaml b/mmv1/products/activedirectory/Peering.yaml index b98c94b7ac59..b760bb8ef788 100644 --- a/mmv1/products/activedirectory/Peering.yaml +++ b/mmv1/products/activedirectory/Peering.yaml @@ -73,7 +73,7 @@ properties: output: true description: | Unique name of the peering in this scope including projects and location using the form: projects/{projectId}/locations/global/peerings/{peeringId}. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'Resource labels that can contain user-provided metadata' - !ruby/object:Api::Type::String diff --git a/mmv1/products/alloydb/Backup.yaml b/mmv1/products/alloydb/Backup.yaml index 36a9f4339914..ee306347295e 100644 --- a/mmv1/products/alloydb/Backup.yaml +++ b/mmv1/products/alloydb/Backup.yaml @@ -92,7 +92,7 @@ properties: required: true immutable: true diff_suppress_func: 'tpgresource.ProjectNumberDiffSuppress' - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'User-defined labels for the alloydb backup.' - !ruby/object:Api::Type::Time diff --git a/mmv1/products/alloydb/Cluster.yaml b/mmv1/products/alloydb/Cluster.yaml index cf597bad4d43..3922c2ddc624 100644 --- a/mmv1/products/alloydb/Cluster.yaml +++ b/mmv1/products/alloydb/Cluster.yaml @@ -106,7 +106,7 @@ properties: output: true description: | The system-generated UID of the resource. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'User-defined labels for the alloydb cluster.' - !ruby/object:Api::Type::NestedObject diff --git a/mmv1/products/apigateway/ApiConfig.yaml b/mmv1/products/apigateway/ApiConfig.yaml index 2c795186cbed..da35b85703d9 100644 --- a/mmv1/products/apigateway/ApiConfig.yaml +++ b/mmv1/products/apigateway/ApiConfig.yaml @@ -120,7 +120,7 @@ properties: output: true description: | The ID of the associated Service Config (https://cloud.google.com/service-infrastructure/docs/glossary#config). - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Resource labels to represent user-provided metadata. diff --git a/mmv1/products/apigateway/ApiResource.yaml b/mmv1/products/apigateway/ApiResource.yaml index f295dd636fee..93ae56e5e75b 100644 --- a/mmv1/products/apigateway/ApiResource.yaml +++ b/mmv1/products/apigateway/ApiResource.yaml @@ -87,7 +87,7 @@ properties: name: 'createTime' description: Creation timestamp in RFC3339 text format. output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Resource labels to represent user-provided metadata. diff --git a/mmv1/products/apigateway/Gateway.yaml b/mmv1/products/apigateway/Gateway.yaml index 5ce68c7f3315..9dc7b3b17b02 100644 --- a/mmv1/products/apigateway/Gateway.yaml +++ b/mmv1/products/apigateway/Gateway.yaml @@ -102,7 +102,7 @@ properties: description: The default API Gateway host name of the form {gatewayId}-{hash}.{region_code}.gateway.dev. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Resource labels to represent user-provided metadata. diff --git a/mmv1/products/artifactregistry/Repository.yaml b/mmv1/products/artifactregistry/Repository.yaml index 4a7e32d73a1c..1ceb42a714f3 100644 --- a/mmv1/products/artifactregistry/Repository.yaml +++ b/mmv1/products/artifactregistry/Repository.yaml @@ -131,7 +131,7 @@ properties: name: description description: |- The user-provided description of the repository. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Labels with user-defined metadata. diff --git a/mmv1/products/beyondcorp/AppConnection.yaml b/mmv1/products/beyondcorp/AppConnection.yaml index 215bac419709..1ebf2c7368fb 100644 --- a/mmv1/products/beyondcorp/AppConnection.yaml +++ b/mmv1/products/beyondcorp/AppConnection.yaml @@ -88,7 +88,7 @@ properties: name: 'displayName' description: | An arbitrary user-provided name for the AppConnection. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Resource labels to represent user provided metadata. diff --git a/mmv1/products/beyondcorp/AppConnector.yaml b/mmv1/products/beyondcorp/AppConnector.yaml index 20a6b3a11bcc..fb8e23bedbf6 100644 --- a/mmv1/products/beyondcorp/AppConnector.yaml +++ b/mmv1/products/beyondcorp/AppConnector.yaml @@ -82,7 +82,7 @@ properties: name: 'displayName' description: | An arbitrary user-provided name for the AppConnector. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Resource labels to represent user provided metadata. diff --git a/mmv1/products/beyondcorp/AppGateway.yaml b/mmv1/products/beyondcorp/AppGateway.yaml index 1eda5d9eeefe..7d6fc2fc42fe 100644 --- a/mmv1/products/beyondcorp/AppGateway.yaml +++ b/mmv1/products/beyondcorp/AppGateway.yaml @@ -98,7 +98,7 @@ properties: name: 'displayName' description: | An arbitrary user-provided name for the AppGateway. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Resource labels to represent user provided metadata. diff --git a/mmv1/products/bigquery/Job.yaml b/mmv1/products/bigquery/Job.yaml index cf12ae9fdf3d..016f76d03a72 100644 --- a/mmv1/products/bigquery/Job.yaml +++ b/mmv1/products/bigquery/Job.yaml @@ -168,7 +168,7 @@ properties: name: 'jobTimeoutMs' description: | Job timeout in milliseconds. If this time limit is exceeded, BigQuery may attempt to terminate the job. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | The labels associated with this job. You can use these to organize and group your jobs. diff --git a/mmv1/products/bigquery/Table.yaml b/mmv1/products/bigquery/Table.yaml index ae9c5bb81666..2c248d787213 100644 --- a/mmv1/products/bigquery/Table.yaml +++ b/mmv1/products/bigquery/Table.yaml @@ -88,7 +88,7 @@ properties: name: 'id' description: 'An opaque ID uniquely identifying the table.' output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | The labels associated with this dataset. You can use these to diff --git a/mmv1/products/certificatemanager/Certificate.yaml b/mmv1/products/certificatemanager/Certificate.yaml index 552364c08bba..a2cee514e99d 100644 --- a/mmv1/products/certificatemanager/Certificate.yaml +++ b/mmv1/products/certificatemanager/Certificate.yaml @@ -95,7 +95,7 @@ properties: name: 'description' description: | A human-readable description of the resource. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'Set of label tags associated with the Certificate resource.' - !ruby/object:Api::Type::String diff --git a/mmv1/products/certificatemanager/CertificateIssuanceConfig.yaml b/mmv1/products/certificatemanager/CertificateIssuanceConfig.yaml index 6a994704207a..fa4cec9f21ac 100644 --- a/mmv1/products/certificatemanager/CertificateIssuanceConfig.yaml +++ b/mmv1/products/certificatemanager/CertificateIssuanceConfig.yaml @@ -109,7 +109,7 @@ properties: accurate to nanoseconds with up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z". output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | 'Set of label tags associated with the CertificateIssuanceConfig resource. diff --git a/mmv1/products/certificatemanager/CertificateMap.yaml b/mmv1/products/certificatemanager/CertificateMap.yaml index 1342e8344e46..96df010f7666 100644 --- a/mmv1/products/certificatemanager/CertificateMap.yaml +++ b/mmv1/products/certificatemanager/CertificateMap.yaml @@ -76,11 +76,10 @@ properties: accurate to nanoseconds with up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z". output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Set of labels associated with a Certificate Map resource. - default_from_api: true - !ruby/object:Api::Type::Array name: 'gclbTargets' description: | diff --git a/mmv1/products/certificatemanager/CertificateMapEntry.yaml b/mmv1/products/certificatemanager/CertificateMapEntry.yaml index 296e342a6920..aa1ac5d57570 100644 --- a/mmv1/products/certificatemanager/CertificateMapEntry.yaml +++ b/mmv1/products/certificatemanager/CertificateMapEntry.yaml @@ -92,13 +92,12 @@ properties: with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z". output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | Set of labels associated with a Certificate Map Entry. An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. - default_from_api: true - !ruby/object:Api::Type::Array name: 'certificates' required: true diff --git a/mmv1/products/certificatemanager/DnsAuthorization.yaml b/mmv1/products/certificatemanager/DnsAuthorization.yaml index fa6e636e7691..bcb50c60c329 100644 --- a/mmv1/products/certificatemanager/DnsAuthorization.yaml +++ b/mmv1/products/certificatemanager/DnsAuthorization.yaml @@ -63,7 +63,7 @@ properties: name: 'description' description: | A human-readable description of the resource. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'Set of label tags associated with the DNS Authorization resource.' diff --git a/mmv1/products/certificatemanager/TrustConfig.yaml b/mmv1/products/certificatemanager/TrustConfig.yaml index d4ff25e5256c..d7395fa22948 100644 --- a/mmv1/products/certificatemanager/TrustConfig.yaml +++ b/mmv1/products/certificatemanager/TrustConfig.yaml @@ -84,7 +84,7 @@ properties: 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". output: true - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: 'Set of label tags associated with the trust config.' immutable: true diff --git a/mmv1/products/cloudfunctions/CloudFunction.yaml b/mmv1/products/cloudfunctions/CloudFunction.yaml index ad310f7293ab..6ac2766e6ffe 100644 --- a/mmv1/products/cloudfunctions/CloudFunction.yaml +++ b/mmv1/products/cloudfunctions/CloudFunction.yaml @@ -129,7 +129,7 @@ properties: description: | The version identifier of the Cloud Function. Each deployment attempt results in a new version of a function being created. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | A set of key/value label pairs associated with this Cloud Function. diff --git a/mmv1/products/cloudfunctions2/Function.yaml b/mmv1/products/cloudfunctions2/Function.yaml index a8ca2d64185a..5b0a0ff36b0a 100644 --- a/mmv1/products/cloudfunctions2/Function.yaml +++ b/mmv1/products/cloudfunctions2/Function.yaml @@ -630,7 +630,7 @@ properties: name: 'updateTime' output: true description: 'The last update timestamp of a Cloud Function.' - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | A set of key/value label pairs associated with this Cloud Function. diff --git a/mmv1/products/cloudrunv2/Job.yaml b/mmv1/products/cloudrunv2/Job.yaml index d8b928f7962f..82bd0618fb85 100644 --- a/mmv1/products/cloudrunv2/Job.yaml +++ b/mmv1/products/cloudrunv2/Job.yaml @@ -129,7 +129,7 @@ properties: output: true description: | A number that monotonically increases every time the user modifies the desired state. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: |- Unstructured key value map that can be used to organize and categorize objects. User-provided labels are shared with Google's billing system, so they can be used to filter, or break down billing charges by team, component, diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index 337e63381f52..daf10dbf9fbb 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -144,7 +144,7 @@ properties: output: true description: | A number that monotonically increases every time the user modifies the desired state. Please note that unlike v1, this is an int64 value. As with most Google APIs, its JSON representation will be a string instead of an integer. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: |- Unstructured key value map that can be used to organize and categorize objects. User-provided labels are shared with Google's billing system, so they can be used to filter, or break down billing charges by team, component, diff --git a/mmv1/products/databasemigrationservice/connectionprofile.yaml b/mmv1/products/databasemigrationservice/connectionprofile.yaml index 62e6fc778024..f9383453a7f0 100644 --- a/mmv1/products/databasemigrationservice/connectionprofile.yaml +++ b/mmv1/products/databasemigrationservice/connectionprofile.yaml @@ -116,7 +116,7 @@ properties: output: true description: | Output only. The timestamp when the resource was created. A timestamp in RFC3339 UTC 'Zulu' format, accurate to nanoseconds. Example: '2014-10-02T15:01:23.045123456Z'. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | The resource labels for connection profile to use to annotate any related underlying resources such as Compute Engine VMs. diff --git a/mmv1/products/datafusion/Instance.yaml b/mmv1/products/datafusion/Instance.yaml index 17f0333f65d8..ccd0efd1c762 100644 --- a/mmv1/products/datafusion/Instance.yaml +++ b/mmv1/products/datafusion/Instance.yaml @@ -141,7 +141,7 @@ properties: name: 'enableRbac' description: | Option to enable granular role-based access control. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | The resource labels for instance to use to annotate any related underlying resources, diff --git a/mmv1/products/dataplex/Datascan.yaml b/mmv1/products/dataplex/Datascan.yaml index 2f0820034380..c3900509e163 100644 --- a/mmv1/products/dataplex/Datascan.yaml +++ b/mmv1/products/dataplex/Datascan.yaml @@ -126,7 +126,7 @@ properties: name: 'displayName' description: | User friendly display name. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | User-defined labels for the scan. A list of key->value pairs. diff --git a/mmv1/products/dataplex/Task.yaml b/mmv1/products/dataplex/Task.yaml index 3a4095794264..66ed12c16dbb 100644 --- a/mmv1/products/dataplex/Task.yaml +++ b/mmv1/products/dataplex/Task.yaml @@ -116,7 +116,7 @@ properties: - :CREATING - :DELETING - :ACTION_REQUIRED - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: | User-defined labels for the task. diff --git a/mmv1/products/datastream/ConnectionProfile.yaml b/mmv1/products/datastream/ConnectionProfile.yaml index 5e5258e765b6..3a8a4d94879f 100644 --- a/mmv1/products/datastream/ConnectionProfile.yaml +++ b/mmv1/products/datastream/ConnectionProfile.yaml @@ -81,7 +81,7 @@ properties: name: 'name' output: true description: The resource's name. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: Labels. - !ruby/object:Api::Type::String diff --git a/mmv1/products/datastream/PrivateConnection.yaml b/mmv1/products/datastream/PrivateConnection.yaml index dcd9a6da8d71..c2a10d6c8bce 100644 --- a/mmv1/products/datastream/PrivateConnection.yaml +++ b/mmv1/products/datastream/PrivateConnection.yaml @@ -59,7 +59,7 @@ properties: name: 'name' output: true description: The resource's name. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: Labels. - !ruby/object:Api::Type::String diff --git a/mmv1/products/datastream/Stream.yaml b/mmv1/products/datastream/Stream.yaml index 039b51a75457..a88ed1eeb73c 100644 --- a/mmv1/products/datastream/Stream.yaml +++ b/mmv1/products/datastream/Stream.yaml @@ -157,7 +157,7 @@ properties: name: 'name' output: true description: The stream's name. - - !ruby/object:Api::Type::KeyValuePairs + - !ruby/object:Api::Type::KeyValueLabels name: 'labels' description: Labels. - !ruby/object:Api::Type::String diff --git a/mmv1/provider/terraform.rb b/mmv1/provider/terraform.rb index 4b89fb535374..512a26b353bf 100644 --- a/mmv1/provider/terraform.rb +++ b/mmv1/provider/terraform.rb @@ -105,7 +105,7 @@ def updatable?(resource, properties) end def force_new?(property, resource) - !property.output && + (!property.output || property.is_a?(Api::Type::KeyValueEffectiveLabels)) && (property.immutable || (resource.immutable && property.update_url.nil? && property.immutable.nil? && (property.parent.nil? || diff --git a/mmv1/templates/terraform/examples/base_configs/test_file.go.erb b/mmv1/templates/terraform/examples/base_configs/test_file.go.erb index 3e9b14c491df..64aa47337ddd 100644 --- a/mmv1/templates/terraform/examples/base_configs/test_file.go.erb +++ b/mmv1/templates/terraform/examples/base_configs/test_file.go.erb @@ -44,9 +44,10 @@ object.examples test_slug = "#{resource_name}_#{example.name.camelize(:lower)}Example" ignore_read = object.all_user_properties - .select{|p| p.url_param_only || p.ignore_read || p.is_a?(Api::Type::ResourceRef) || p.is_a?(Api::Type::KeyValueLabels) || p.is_a?(Api::Type::KeyValueAnnotations) || p.is_a?(Api::Type::KeyValueTerraformLabels)} + .select{|p| p.url_param_only || p.ignore_read || p.is_a?(Api::Type::ResourceRef)} .map { |p| p.name.underscore } .concat(example.ignore_read_extra) + .concat(object.ignore_read_labels_fields(object.properties_with_excluded)) # Use explicit version for the example if given. # Otherwise, use object version. diff --git a/mmv1/templates/terraform/examples/certificate_manager_google_managed_certificate_dns.tf.erb b/mmv1/templates/terraform/examples/certificate_manager_google_managed_certificate_dns.tf.erb index 48d499afeff7..6e457875fbd2 100644 --- a/mmv1/templates/terraform/examples/certificate_manager_google_managed_certificate_dns.tf.erb +++ b/mmv1/templates/terraform/examples/certificate_manager_google_managed_certificate_dns.tf.erb @@ -2,6 +2,9 @@ resource "google_certificate_manager_certificate" "<%= ctx[:primary_resource_id] name = "<%= ctx[:vars]['cert_name'] %>" description = "The default cert" scope = "EDGE_CACHE" + labels = { + env = "test" + } managed { domains = [ google_certificate_manager_dns_authorization.instance.domain, diff --git a/mmv1/templates/terraform/expand_property_method.erb b/mmv1/templates/terraform/expand_property_method.erb index 880242320bd5..d74d7bcc777c 100644 --- a/mmv1/templates/terraform/expand_property_method.erb +++ b/mmv1/templates/terraform/expand_property_method.erb @@ -75,6 +75,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d t func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { transformed := make(map[string]interface{}) <% property.nested_properties.each do |prop| -%> +<% next if prop.is_a?(Api::Type::KeyValuePairs) && prop.ignore_write -%> <% schemaPrefix = prop.flatten_object ? "nil" : "d.Get( \"#{prop.name.underscore}\" )" -%> transformed<%= titlelize_property(prop) -%>, err := expand<%= prefix -%><%= titlelize_property(property) -%><%= titlelize_property(prop) -%>(<%= schemaPrefix -%>, d, config) if err != nil { diff --git a/mmv1/third_party/terraform/acctest/test_utils.go.erb b/mmv1/third_party/terraform/acctest/test_utils.go.erb index bf081eac3c9a..3fc319222497 100644 --- a/mmv1/third_party/terraform/acctest/test_utils.go.erb +++ b/mmv1/third_party/terraform/acctest/test_utils.go.erb @@ -50,6 +50,12 @@ func CheckDataSourceStateMatchesResourceStateWithIgnores(dataSourceName, resourc if _, ok := ignoreFields[k]; ok { continue } + if _, ok := ignoreFields["labels.%"]; ok && strings.HasPrefix(k, "labels.") { + continue + } + if _, ok := ignoreFields["terraform_labels.%"]; ok && strings.HasPrefix(k, "terraform_labels.") { + continue + } if k == "%" { continue } diff --git a/mmv1/third_party/terraform/services/activedirectory/resource_active_directory_domain_update_test.go b/mmv1/third_party/terraform/services/activedirectory/resource_active_directory_domain_update_test.go index f88bc7f5e808..de9069c50cc4 100644 --- a/mmv1/third_party/terraform/services/activedirectory/resource_active_directory_domain_update_test.go +++ b/mmv1/third_party/terraform/services/activedirectory/resource_active_directory_domain_update_test.go @@ -39,7 +39,7 @@ func TestAccActiveDirectoryDomain_update(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"domain_name"}, + ImportStateVerifyIgnore: []string{"domain_name", "labels", "terraform_labels"}, }, { Config: testAccADDomainUpdate(context), @@ -48,7 +48,7 @@ func TestAccActiveDirectoryDomain_update(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"domain_name"}, + ImportStateVerifyIgnore: []string{"domain_name", "labels", "terraform_labels"}, }, { Config: testAccADDomainBasic(context), @@ -57,7 +57,7 @@ func TestAccActiveDirectoryDomain_update(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"domain_name"}, + ImportStateVerifyIgnore: []string{"domain_name", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go index 33091f142314..4223e1a81555 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_backup_test.go @@ -28,7 +28,7 @@ func TestAccAlloydbBackup_update(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, { Config: testAccAlloydbBackup_update(context), @@ -37,7 +37,7 @@ func TestAccAlloydbBackup_update(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) @@ -190,7 +190,7 @@ func TestAccAlloydbBackup_usingCMEK(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go index 0539c908324b..f9394bced4c2 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go @@ -26,7 +26,7 @@ func TestAccAlloydbCluster_update(t *testing.T) { ResourceName: "google_alloydb_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"}, + ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location", "labels", "terraform_labels"}, }, { Config: testAccAlloydbCluster_update(context), @@ -35,7 +35,7 @@ func TestAccAlloydbCluster_update(t *testing.T) { ResourceName: "google_alloydb_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"}, + ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location", "labels", "terraform_labels"}, }, { Config: testAccAlloydbCluster_alloydbClusterBasicExample(context), diff --git a/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository_test.go b/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository_test.go index 7c663fbe0a60..735bec2d3beb 100644 --- a/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository_test.go +++ b/mmv1/third_party/terraform/services/artifactregistry/data_source_artifact_registry_repository_test.go @@ -23,8 +23,8 @@ func TestAccDataSourceGoogleArtifactRegistryRepositoryConfig(t *testing.T) { { Config: testAccDataSourceGoogleArtifactRegistryRepositoryConfig(context), Check: resource.ComposeTestCheckFunc( - acctest.CheckDataSourceStateMatchesResourceState(funcDataName, - "google_artifact_registry_repository.my-repo"), + acctest.CheckDataSourceStateMatchesResourceStateWithIgnores(funcDataName, + "google_artifact_registry_repository.my-repo", map[string]struct{}{"labels.%": {}, "terraform_labels.%": {}}), ), }, }, @@ -38,6 +38,10 @@ resource "google_artifact_registry_repository" "my-repo" { repository_id = "tf-test-my-repository%{random_suffix}" description = "example docker repository%{random_suffix}" format = "DOCKER" + labels = { + my_key = "my_val" + other_key = "other_val" + } } data "google_artifact_registry_repository" "my-repo" { diff --git a/mmv1/third_party/terraform/services/artifactregistry/resource_artifact_registry_repository_test.go.erb b/mmv1/third_party/terraform/services/artifactregistry/resource_artifact_registry_repository_test.go.erb index d098eb1c0edc..6f409d267936 100644 --- a/mmv1/third_party/terraform/services/artifactregistry/resource_artifact_registry_repository_test.go.erb +++ b/mmv1/third_party/terraform/services/artifactregistry/resource_artifact_registry_repository_test.go.erb @@ -26,6 +26,7 @@ func TestAccArtifactRegistryRepository_update(t *testing.T) { ResourceName: "google_artifact_registry_repository.test", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccArtifactRegistryRepository_update2(repositoryID), @@ -34,6 +35,7 @@ func TestAccArtifactRegistryRepository_update(t *testing.T) { ResourceName: "google_artifact_registry_repository.test", ImportState: true, ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_job_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_job_test.go index 9de93bb6a2f7..3e8b4b832e3f 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_job_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_job_test.go @@ -32,7 +32,7 @@ func TestAccBigQueryJob_withLocation(t *testing.T) { ImportStateId: importID, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go index cc5f910604d3..cb3482a9532b 100644 --- a/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go +++ b/mmv1/third_party/terraform/services/bigquery/resource_bigquery_table_test.go @@ -1031,7 +1031,7 @@ func TestAccBigQueryDataTable_jsonEquivalency(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, { Config: testAccBigQueryTable_jsonEqModeRemoved(datasetID, tableID), @@ -1040,7 +1040,7 @@ func TestAccBigQueryDataTable_jsonEquivalency(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, }, }) @@ -1090,7 +1090,7 @@ func TestAccBigQueryDataTable_expandArray(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, { Config: testAccBigQueryTable_arrayExpanded(datasetID, tableID), @@ -1099,7 +1099,7 @@ func TestAccBigQueryDataTable_expandArray(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, }, }) @@ -1123,7 +1123,7 @@ func TestAccBigQueryTable_allowDestroy(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"deletion_protection", "labels", "terraform_labels"}, }, { Config: testAccBigQueryTable_noAllowDestroy(datasetID, tableID), diff --git a/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go b/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go index f824e92ce94c..c25f72515e87 100644 --- a/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go +++ b/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go @@ -26,7 +26,7 @@ func TestAccCertificateManagerDnsAuthorization_update(t *testing.T) { ResourceName: "google_certificate_manager_dns_authorization.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name"}, + ImportStateVerifyIgnore: []string{"name", "labels", "terraform_labels"}, }, { Config: testAccCertificateManagerDnsAuthorization_update1(context), @@ -35,7 +35,7 @@ func TestAccCertificateManagerDnsAuthorization_update(t *testing.T) { ResourceName: "google_certificate_manager_dns_authorization.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name"}, + ImportStateVerifyIgnore: []string{"name", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_trust_config_test.go b/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_trust_config_test.go index 89a5d4d0a9ad..b84cbb0530f6 100644 --- a/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_trust_config_test.go +++ b/mmv1/third_party/terraform/services/certificatemanager/resource_certificate_manager_trust_config_test.go @@ -23,17 +23,19 @@ func TestAccCertificateManagerTrustConfig_update(t *testing.T) { Config: testAccCertificateManagerTrustConfig_update0(context), }, { - ResourceName: "google_certificate_manager_trust_config.default", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_certificate_manager_trust_config.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccCertificateManagerTrustConfig_update1(context), }, { - ResourceName: "google_certificate_manager_trust_config.default", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_certificate_manager_trust_config.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function_test.go.erb b/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function_test.go.erb index 97805cafbf09..9bf727547801 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function_test.go.erb +++ b/mmv1/third_party/terraform/services/cloudfunctions/resource_cloudfunctions_function_test.go.erb @@ -80,7 +80,7 @@ func TestAccCloudFunctionsFunction_basic(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, }, }) @@ -117,7 +117,7 @@ func TestAccCloudFunctionsFunction_update(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctionsFunction_updated(functionName, bucketName, zipFileUpdatePath, random_suffix), @@ -150,7 +150,7 @@ func TestAccCloudFunctionsFunction_update(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, }, }) @@ -425,7 +425,7 @@ func TestAccCloudFunctionsFunction_vpcConnector(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctionsFunction_vpcConnector(projectNumber, networkName, functionName, bucketName, zipFilePath, "10.20.0.0/28", vpcConnectorName+"-update"), @@ -434,7 +434,7 @@ func TestAccCloudFunctionsFunction_vpcConnector(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go b/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go index 3769b961f991..7f4d5db5baf7 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go +++ b/mmv1/third_party/terraform/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go @@ -24,9 +24,11 @@ func TestAccDataSourceGoogleCloudFunctions2Function_basic(t *testing.T) { { Config: testAccDataSourceGoogleCloudFunctions2FunctionConfig(functionName, bucketName, zipFilePath), + // As the value of "labels" and "terraform_labels" in the state is dependent on the configuration, + // and these fields are not set in the configuration of the data source, so these fields are empty in the state of the data source. Check: resource.ComposeTestCheckFunc( acctest.CheckDataSourceStateMatchesResourceStateWithIgnores(funcDataNameHttp, - "google_cloudfunctions2_function.function_http_v2", map[string]struct{}{"build_config.0.source.0.storage_source.0.bucket": {}, "build_config.0.source.0.storage_source.0.object": {}}), + "google_cloudfunctions2_function.function_http_v2", map[string]struct{}{"build_config.0.source.0.storage_source.0.bucket": {}, "build_config.0.source.0.storage_source.0.object": {}, "labels.%": {}, "terraform_labels.%": {}}), ), }, }, @@ -35,6 +37,12 @@ func TestAccDataSourceGoogleCloudFunctions2Function_basic(t *testing.T) { func testAccDataSourceGoogleCloudFunctions2FunctionConfig(functionName, bucketName, zipFilePath string) string { return fmt.Sprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + } +} + resource "google_storage_bucket" "bucket" { name = "%s" location = "US" @@ -50,7 +58,9 @@ resource "google_cloudfunctions2_function" "function_http_v2" { name = "%s" location = "us-central1" description = "a new function" - + labels = { + env = "test" + } build_config { runtime = "nodejs12" entry_point = "helloHttp" diff --git a/mmv1/third_party/terraform/services/cloudfunctions2/resource_cloudfunctions2_function_test.go b/mmv1/third_party/terraform/services/cloudfunctions2/resource_cloudfunctions2_function_test.go index 443a86fa0e94..ab82a584fbca 100644 --- a/mmv1/third_party/terraform/services/cloudfunctions2/resource_cloudfunctions2_function_test.go +++ b/mmv1/third_party/terraform/services/cloudfunctions2/resource_cloudfunctions2_function_test.go @@ -28,7 +28,7 @@ func TestAccCloudFunctions2Function_update(t *testing.T) { ResourceName: "google_cloudfunctions2_function.terraform-test2", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctions2Function_test_update(context), @@ -37,7 +37,7 @@ func TestAccCloudFunctions2Function_update(t *testing.T) { ResourceName: "google_cloudfunctions2_function.terraform-test2", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctions2Function_test_redeploy(context), @@ -46,7 +46,7 @@ func TestAccCloudFunctions2Function_update(t *testing.T) { ResourceName: "google_cloudfunctions2_function.terraform-test2", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -70,6 +70,9 @@ resource "google_cloudfunctions2_function" "terraform-test2" { name = "tf-test-test-function%{random_suffix}" location = "us-central1" description = "a new function" + labels = { + env = "test" + } build_config { runtime = "nodejs12" @@ -109,7 +112,10 @@ resource "google_cloudfunctions2_function" "terraform-test2" { name = "tf-test-test-function%{random_suffix}" location = "us-central1" description = "an updated function" - + labels = { + env = "test-update" + } + build_config { runtime = "nodejs12" entry_point = "helloHttp" diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go index 7620f5b6978b..4b03127fa114 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go @@ -26,7 +26,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "launch_stage", "annotations"}, + ImportStateVerifyIgnore: []string{"location", "launch_stage", "labels", "terraform_labels", "annotations"}, }, { Config: testAccCloudRunV2Job_cloudrunv2JobFullUpdate(context), @@ -35,7 +35,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "launch_stage", "annotations"}, + ImportStateVerifyIgnore: []string{"location", "launch_stage", "labels", "terraform_labels", "annotations"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go index feb6bfbd9959..b7ff80105dda 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go @@ -30,7 +30,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations", "labels", "terraform_labels"}, }, { Config: testAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(context), @@ -39,7 +39,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go b/mmv1/third_party/terraform/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go index 598da3507871..439c8b395198 100644 --- a/mmv1/third_party/terraform/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go +++ b/mmv1/third_party/terraform/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go @@ -25,7 +25,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_update(t *testing.T) { ResourceName: "google_database_migration_service_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password", "labels", "terraform_labels"}, }, { Config: testAccDatabaseMigrationServiceConnectionProfile_update(suffix), @@ -34,7 +34,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_update(t *testing.T) { ResourceName: "google_database_migration_service_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password", "labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/datafusion/resource_data_fusion_instance_test.go b/mmv1/third_party/terraform/services/datafusion/resource_data_fusion_instance_test.go index f245f7334cce..b741c39a53b6 100644 --- a/mmv1/third_party/terraform/services/datafusion/resource_data_fusion_instance_test.go +++ b/mmv1/third_party/terraform/services/datafusion/resource_data_fusion_instance_test.go @@ -21,17 +21,19 @@ func TestAccDataFusionInstance_update(t *testing.T) { Config: testAccDataFusionInstance_basic(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccDataFusionInstance_updated(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) @@ -97,17 +99,19 @@ func TestAccDataFusionInstanceEnterprise_update(t *testing.T) { Config: testAccDataFusionInstanceEnterprise_basic(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccDataFusionInstanceEnterprise_updated(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/mmv1/third_party/terraform/services/datastream/resource_datastream_stream_test.go b/mmv1/third_party/terraform/services/datastream/resource_datastream_stream_test.go index dde019ab0af1..ad71b868cd22 100644 --- a/mmv1/third_party/terraform/services/datastream/resource_datastream_stream_test.go +++ b/mmv1/third_party/terraform/services/datastream/resource_datastream_stream_test.go @@ -33,7 +33,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { Config: testAccDatastreamStream_datastreamStreamBasicUpdate(context, "RUNNING", true), @@ -43,7 +43,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { Config: testAccDatastreamStream_datastreamStreamBasicUpdate(context, "PAUSED", true), @@ -53,7 +53,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { Config: testAccDatastreamStream_datastreamStreamBasicUpdate(context, "RUNNING", true), @@ -63,7 +63,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { // Disable prevent_destroy From 56aed360a5c88b6cbcdee6efe986a41e6f213489 Mon Sep 17 00:00:00 2001 From: Dennis Kugelmann Date: Fri, 15 Sep 2023 23:25:46 +0000 Subject: [PATCH 097/476] Add Firestore deletion protection (#8906) * Add Firestore deletion protection * Reformat * Add test for updating delete_protection_state * Make deleteProtectionState skip auto-generated tests * Add a dedicated example for delete protection --- mmv1/products/firestore/Database.yaml | 13 +++++ ...ore_database_with_delete_protection.tf.erb | 13 +++++ ...urce_firestore_database_update_test.go.erb | 52 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 mmv1/templates/terraform/examples/firestore_database_with_delete_protection.tf.erb diff --git a/mmv1/products/firestore/Database.yaml b/mmv1/products/firestore/Database.yaml index 1b4bc7c8978f..c3f867236d45 100644 --- a/mmv1/products/firestore/Database.yaml +++ b/mmv1/products/firestore/Database.yaml @@ -99,6 +99,10 @@ examples: - etag vars: project_id: 'my-project' + - !ruby/object:Provider::Terraform::Examples + name: 'firestore_database_with_delete_protection' + primary_resource_id: 'database' + skip_test: true properties: - !ruby/object:Api::Type::String name: name @@ -167,6 +171,15 @@ properties: that is returned from the Cloud Datastore APIs in Google App Engine first generation runtimes. This value may be empty in which case the appid to use for URL-encoded keys is the project_id (eg: foo instead of v~foo). output: true + - !ruby/object:Api::Type::Enum + name: deleteProtectionState + description: | + State of delete protection for the database. + values: + - :DELETE_PROTECTION_STATE_UNSPECIFIED + - :DELETE_PROTECTION_ENABLED + - :DELETE_PROTECTION_DISABLED + default_from_api: true - !ruby/object:Api::Type::Fingerprint name: etag description: | diff --git a/mmv1/templates/terraform/examples/firestore_database_with_delete_protection.tf.erb b/mmv1/templates/terraform/examples/firestore_database_with_delete_protection.tf.erb new file mode 100644 index 000000000000..7fe3ed71bf7a --- /dev/null +++ b/mmv1/templates/terraform/examples/firestore_database_with_delete_protection.tf.erb @@ -0,0 +1,13 @@ +resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" { + project = google_project.project.project_id + name = "my-database" + location_id = "nam5" + type = "FIRESTORE_NATIVE" + + # Prevents accidental deletion of the database. + # To delete the database, first set this field to `DELETE_PROTECTION_DISABLED`, apply the changes. + # Then delete the database resource and apply the changes again. + delete_protection_state = "DELETE_PROTECTION_ENABLED" + + depends_on = [google_project_service.firestore] +} diff --git a/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb b/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb index abdc7c69803b..4f895dc5ea06 100644 --- a/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb +++ b/mmv1/third_party/terraform/services/firestore/resource_firestore_database_update_test.go.erb @@ -82,6 +82,42 @@ func TestAccFirestoreDatabase_updatePitrEnablement(t *testing.T) { }) } +func TestAccFirestoreDatabase_updateDeleteProtectionState(t *testing.T) { + t.Parallel() + + orgId := envvar.GetTestOrgFromEnv(t) + billingAccount := envvar.GetTestBillingAccountFromEnv(t) + randomSuffix := 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: testAccFirestoreDatabase_deleteProtectionState(orgId, billingAccount, randomSuffix, "DELETE_PROTECTION_ENABLED"), + }, + { + ResourceName: "google_firestore_database.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"etag", "project"}, + }, + { + Config: testAccFirestoreDatabase_deleteProtectionState(orgId, billingAccount, randomSuffix, "DELETE_PROTECTION_DISABLED"), + }, + { + ResourceName: "google_firestore_database.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"etag", "project"}, + }, + }, + }) +} + func testAccFirestoreDatabase_basicDependencies(orgId, billingAccount string, randomSuffix string) string { return fmt.Sprintf(` resource "google_project" "default" { @@ -138,3 +174,19 @@ resource "google_firestore_database" "default" { } `, pointInTimeRecoveryEnablement) } + +func testAccFirestoreDatabase_deleteProtectionState(orgId, billingAccount string, randomSuffix string, deleteProtectionState string) string { + return testAccFirestoreDatabase_basicDependencies(orgId, billingAccount, randomSuffix) + fmt.Sprintf(` + +resource "google_firestore_database" "default" { + name = "(default)" + type = "DATASTORE_MODE" + location_id = "nam5" + delete_protection_state = "%s" + + project = google_project.default.project_id + + depends_on = [google_project_service.firestore] +} +`, deleteProtectionState) +} From 93005a9fb55cef69032fde5f60764fb57231c615 Mon Sep 17 00:00:00 2001 From: abheda-crest <105624942+abheda-crest@users.noreply.github.com> Date: Mon, 18 Sep 2023 20:44:43 +0530 Subject: [PATCH 098/476] Replaced the panic statement with error in `google_secret_manager_secret_version` resource import function (#8923) --- mmv1/templates/terraform/custom_import/secret_version.go.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/templates/terraform/custom_import/secret_version.go.erb b/mmv1/templates/terraform/custom_import/secret_version.go.erb index 01404f0fc19a..2119c44884c5 100644 --- a/mmv1/templates/terraform/custom_import/secret_version.go.erb +++ b/mmv1/templates/terraform/custom_import/secret_version.go.erb @@ -11,7 +11,7 @@ parts := secretRegex.FindStringSubmatch(name) if len(parts) != 2 { - panic(fmt.Sprintf("Version name does not fit the format `projects/{{project}}/secrets/{{secret}}/versions/{{version}}`")) + return nil, fmt.Errorf("Version name does not fit the format `projects/{{project}}/secrets/{{secret}}/versions/{{version}}`") } if err := d.Set("secret", parts[1]); err != nil { return nil, fmt.Errorf("Error setting secret: %s", err) From c20afbd14c687660afa07070829f89a649ba68bb Mon Sep 17 00:00:00 2001 From: vmiglani <142545940+vmiglani@users.noreply.github.com> Date: Mon, 18 Sep 2023 08:29:07 -0700 Subject: [PATCH 099/476] [AlloyDB] Named IP Range Support (#8963) --- mmv1/products/alloydb/Cluster.yaml | 27 +++++- .../alloydb/resource_alloydb_cluster_test.go | 91 +++++++++++++++++++ .../alloydb/resource_alloydb_instance_test.go | 62 +++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) diff --git a/mmv1/products/alloydb/Cluster.yaml b/mmv1/products/alloydb/Cluster.yaml index cf597bad4d43..9b98be251433 100644 --- a/mmv1/products/alloydb/Cluster.yaml +++ b/mmv1/products/alloydb/Cluster.yaml @@ -179,12 +179,37 @@ properties: output: true - !ruby/object:Api::Type::String name: 'network' - required: true + exactly_one_of: + - network + - network_config.0.network + default_from_api: true + deprecation_message: >- + `network` is deprecated and will be removed in a future major release. Instead, use `network_config` to define the network configuration. description: | The relative resource name of the VPC network on which the instance can be accessed. It is specified in the following form: "projects/{projectNumber}/global/networks/{network_id}". diff_suppress_func: 'tpgresource.ProjectNumberDiffSuppress' + - !ruby/object:Api::Type::NestedObject + name: 'networkConfig' + description: | + Metadata related to network configuration. + default_from_api: true + properties: + - !ruby/object:Api::Type::String + name: network + exactly_one_of: + - network + - network_config.0.network + description: | + The resource link for the VPC network in which cluster resources are created and from which they are accessible via Private IP. The network must belong to the same project as the cluster. + It is specified in the form: "projects/{projectNumber}/global/networks/{network_id}". + diff_suppress_func: 'tpgresource.ProjectNumberDiffSuppress' + - !ruby/object:Api::Type::String + name: allocatedIpRange + description: | + The name of the allocated IP range for the private IP AlloyDB cluster. For example: "google-managed-services-default". + If set, the instance IPs for this cluster will be created in the allocated range. - !ruby/object:Api::Type::String name: 'displayName' description: | diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go index 0539c908324b..3d8ad93a789a 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_cluster_test.go @@ -1092,3 +1092,94 @@ resource "google_kms_crypto_key_iam_binding" "crypto_key" { } `, context) } + +// Ensures cluster creation works with networkConfig. +func TestAccAlloydbCluster_withNetworkConfig(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccAlloydbCluster_withNetworkConfig(context), + }, + { + ResourceName: "google_alloydb_cluster.default", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAlloydbCluster_withNetworkConfig(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_alloydb_cluster" "default" { + cluster_id = "tf-test-alloydb-cluster%{random_suffix}" + location = "us-central1" + network_config { + network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}" + } +} +data "google_project" "project" {} +resource "google_compute_network" "default" { + name = "tf-test-alloydb-cluster%{random_suffix}" +} +`, context) +} + +// Ensures cluster creation works with networkConfig and a specified allocated IP range. +func TestAccAlloydbCluster_withNetworkConfigAndAllocatedIPRange(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccAlloydbCluster_withNetworkConfigAndAllocatedIPRange(context), + }, + { + ResourceName: "google_alloydb_cluster.default", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAlloydbCluster_withNetworkConfigAndAllocatedIPRange(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_alloydb_cluster" "default" { + cluster_id = "tf-test-alloydb-cluster%{random_suffix}" + location = "us-central1" + network_config { + network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}" + allocated_ip_range = google_compute_global_address.private_ip_alloc.name + } +} +data "google_project" "project" {} +resource "google_compute_network" "default" { + name = "tf-test-alloydb-cluster%{random_suffix}" +} +resource "google_compute_global_address" "private_ip_alloc" { + name = "tf-test-alloydb-cluster%{random_suffix}" + address_type = "INTERNAL" + purpose = "VPC_PEERING" + prefix_length = 16 + network = google_compute_network.default.id + } + +`, context) +} diff --git a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go index 944d04c25ad1..71df2654de19 100644 --- a/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go +++ b/mmv1/third_party/terraform/services/alloydb/resource_alloydb_instance_test.go @@ -406,3 +406,65 @@ resource "google_service_networking_connection" "vpc_connection" { } `, context) } + +// This test passes if we are able to create a primary instance by specifying network_config.network and network_config.allocated_ip_range +func TestAccAlloydbInstance_createInstanceWithNetworkConfigAndAllocatedIPRange(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "network_name": acctest.BootstrapSharedTestNetwork(t, "alloydbinstance-network-config"), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckAlloydbInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccAlloydbInstance_createInstanceWithNetworkConfigAndAllocatedIPRange(context), + }, + }, + }) +} + +func testAccAlloydbInstance_createInstanceWithNetworkConfigAndAllocatedIPRange(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_alloydb_instance" "default" { + cluster = google_alloydb_cluster.default.name + instance_id = "tf-test-alloydb-instance%{random_suffix}" + instance_type = "PRIMARY" + depends_on = [google_service_networking_connection.vpc_connection] +} + +resource "google_alloydb_cluster" "default" { + cluster_id = "tf-test-alloydb-cluster%{random_suffix}" + location = "us-central1" + network_config { + network = data.google_compute_network.default.id + allocated_ip_range = google_compute_global_address.private_ip_alloc.name + } + +} + +data "google_project" "project" {} + +data "google_compute_network" "default" { + name = "%{network_name}" +} + +resource "google_compute_global_address" "private_ip_alloc" { + name = "tf-test-alloydb-cluster%{random_suffix}" + address_type = "INTERNAL" + purpose = "VPC_PEERING" + prefix_length = 16 + network = data.google_compute_network.default.id +} + +resource "google_service_networking_connection" "vpc_connection" { + network = data.google_compute_network.default.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name] +} +`, context) +} From 6e03ba531e08763cb99ada2a851d19fcf9ef844f Mon Sep 17 00:00:00 2001 From: hao-nan-li <100219545+hao-nan-li@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:13:30 -0700 Subject: [PATCH 100/476] Add sweeper to firestore_index (#8974) --- mmv1/products/firestore/Index.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/mmv1/products/firestore/Index.yaml b/mmv1/products/firestore/Index.yaml index 658f0e03b4fa..de51c1c14c6d 100644 --- a/mmv1/products/firestore/Index.yaml +++ b/mmv1/products/firestore/Index.yaml @@ -42,7 +42,6 @@ async: !ruby/object:Api::OpAsync path: 'error' message: 'message' autogen_async: true -skip_sweeper: true import_format: ['{{name}}'] docs: !ruby/object:Provider::Terraform::Docs warning: | From da39fa444f4d17af17663824a4bc8c09c9f35235 Mon Sep 17 00:00:00 2001 From: jeperetz Date: Mon, 18 Sep 2023 11:55:40 -0700 Subject: [PATCH 101/476] promote node_pool_auto_config field to GA provider (#8951) --- .../container/resource_container_cluster.go.erb | 16 +--------------- .../resource_container_cluster_test.go.erb | 4 ---- .../docs/r/container_cluster.html.markdown | 6 +++--- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb index 19b8c98d860b..998718fb29ec 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb @@ -1403,7 +1403,6 @@ func ResourceContainerCluster() *schema.Resource { "node_pool_defaults": clusterSchemaNodePoolDefaults(), -<% unless version == "ga" -%> "node_pool_auto_config": { Type: schema.TypeList, Optional: true, @@ -1431,7 +1430,6 @@ func ResourceContainerCluster() *schema.Resource { }, }, }, -<% end -%> "node_version": { Type: schema.TypeString, @@ -2182,8 +2180,8 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er NotificationConfig: expandNotificationConfig(d.Get("notification_config")), ConfidentialNodes: expandConfidentialNodes(d.Get("confidential_nodes")), ResourceLabels: tpgresource.ExpandStringMap(d, "resource_labels"), -<% unless version == 'ga' -%> NodePoolAutoConfig: expandNodePoolAutoConfig(d.Get("node_pool_auto_config")), +<% unless version == 'ga' -%> ProtectConfig: expandProtectConfig(d.Get("protect_config")), <% end -%> CostManagementConfig: expandCostManagementConfig(d.Get("cost_management_config")), @@ -2318,11 +2316,9 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er cluster.MonitoringConfig = expandMonitoringConfig(v) } -<% unless version == 'ga' -%> if err := validateNodePoolAutoConfig(cluster); err != nil { return err } -<% end -%> if err := validatePrivateClusterConfig(cluster); err != nil { return err @@ -2807,11 +2803,9 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro return err } -<% unless version == 'ga' -%> if err := d.Set("node_pool_auto_config", flattenNodePoolAutoConfig(cluster.NodePoolAutoConfig)); err != nil { return err } -<% end -%> if err := d.Set("node_pool_defaults", flattenNodePoolDefaults(cluster.NodePoolDefaults)); err != nil { return err @@ -4018,7 +4012,6 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] GKE cluster %s Security Posture Config has been updated to %#v", d.Id(), req.Update.DesiredSecurityPostureConfig) } -<% unless version == 'ga' -%> if d.HasChange("node_pool_auto_config.0.network_tags.0.tags") { tags := d.Get("node_pool_auto_config.0.network_tags.0.tags").([]interface{}) @@ -4039,7 +4032,6 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] GKE cluster %s node pool auto config network tags have been updated", d.Id()) } -<% end -%> d.Partial(false) @@ -5298,7 +5290,6 @@ func flattenNodePoolDefaults(c *container.NodePoolDefaults) []map[string]interfa return []map[string]interface{}{result} } -<% unless version == 'ga' -%> func expandNodePoolAutoConfig(configured interface{}) *container.NodePoolAutoConfig { l := configured.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -5326,7 +5317,6 @@ func expandNodePoolAutoConfigNetworkTags(configured interface{}) *container.Netw } return nt } -<% end -%> func flattenNotificationConfig(c *container.NotificationConfig) []map[string]interface{} { if c == nil { @@ -6052,7 +6042,6 @@ func flattenManagedPrometheusConfig(c *container.ManagedPrometheusConfig) []map[ } } -<% unless version == 'ga' -%> func flattenNodePoolAutoConfig(c *container.NodePoolAutoConfig) []map[string]interface{} { if c == nil { return nil @@ -6077,7 +6066,6 @@ func flattenNodePoolAutoConfigNetworkTags(c *container.NetworkTags) []map[string } return []map[string]interface{}{result} } -<% end -%> func resourceContainerClusterStateImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { config := meta.(*transport_tpg.Config) @@ -6301,7 +6289,6 @@ func BinaryAuthorizationDiffSuppress(k, old, new string, r *schema.ResourceData) return false } -<% unless version == 'ga' -%> func validateNodePoolAutoConfig(cluster *container.Cluster) error { if cluster == nil || cluster.NodePoolAutoConfig == nil { return nil @@ -6314,7 +6301,6 @@ func validateNodePoolAutoConfig(cluster *container.Cluster) error { return nil } -<% end -%> func containerClusterSurgeSettingsCustomizeDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { if v, ok := d.GetOk("cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.strategy"); ok { diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb index 91f4c3b4e3ea..fc9635d20137 100644 --- a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb +++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb @@ -2521,7 +2521,6 @@ func TestAccContainerCluster_autoprovisioningDefaultsUpgradeSettings(t *testing. }) } -<% unless version == 'ga' -%> func TestAccContainerCluster_nodeAutoprovisioningNetworkTags(t *testing.T) { t.Parallel() @@ -2548,7 +2547,6 @@ func TestAccContainerCluster_nodeAutoprovisioningNetworkTags(t *testing.T) { }, }) } -<% end -%> func TestAccContainerCluster_withShieldedNodes(t *testing.T) { t.Parallel() @@ -2660,7 +2658,6 @@ func TestAccContainerCluster_errorAutopilotLocation(t *testing.T) { }) } -<% unless version == 'ga' -%> func TestAccContainerCluster_withAutopilotNetworkTags(t *testing.T) { t.Parallel() @@ -2685,7 +2682,6 @@ func TestAccContainerCluster_withAutopilotNetworkTags(t *testing.T) { }, }) } -<% end -%> func TestAccContainerCluster_withWorkloadIdentityConfig(t *testing.T) { t.Parallel() diff --git a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown index 3a12ce9213ea..c75c9a6371c4 100644 --- a/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -268,7 +268,7 @@ region are guaranteed to support the same version. to say "these are the _only_ node pools associated with this cluster", use the [google_container_node_pool](container_node_pool.html) resource instead of this property. -* `node_pool_auto_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Node pool configs that apply to auto-provisioned node pools in +* `node_pool_auto_config` - (Optional) Node pool configs that apply to auto-provisioned node pools in [autopilot](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison) clusters and [node auto-provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning)-enabled clusters. Structure is [documented below](#nested_node_pool_auto_config). @@ -1027,11 +1027,11 @@ workload_identity_config { The `node_pool_auto_config` block supports: -* `network_tags` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - The network tag config for the cluster's automatically provisioned node pools. +* `network_tags` (Optional) - The network tag config for the cluster's automatically provisioned node pools. The `network_tags` block supports: -* `tags` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - List of network tags applied to auto-provisioned node pools. +* `tags` (Optional) - List of network tags applied to auto-provisioned node pools. ```hcl node_pool_auto_config { From 1006ea1d53697696d62900bf56574f6895962560 Mon Sep 17 00:00:00 2001 From: Maciej Murakowski <71409499+mmurakowski-verily@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:06:16 -0400 Subject: [PATCH 102/476] Adding google_dialogflow_cx_security_settings resource (#8925) --- .../dialogflowcx/SecuritySettings.yaml | 162 ++++++++++++++++++ ...ialogflowcx_security_settings_basic.tf.erb | 6 + ...dialogflowcx_security_settings_full.tf.erb | 53 ++++++ ...ce_dialogflow_cx_security_settings_test.go | 113 ++++++++++++ 4 files changed, 334 insertions(+) create mode 100644 mmv1/products/dialogflowcx/SecuritySettings.yaml create mode 100644 mmv1/templates/terraform/examples/dialogflowcx_security_settings_basic.tf.erb create mode 100644 mmv1/templates/terraform/examples/dialogflowcx_security_settings_full.tf.erb create mode 100644 mmv1/third_party/terraform/services/dialogflowcx/resource_dialogflow_cx_security_settings_test.go diff --git a/mmv1/products/dialogflowcx/SecuritySettings.yaml b/mmv1/products/dialogflowcx/SecuritySettings.yaml new file mode 100644 index 000000000000..1c4103c725d4 --- /dev/null +++ b/mmv1/products/dialogflowcx/SecuritySettings.yaml @@ -0,0 +1,162 @@ +# 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: 'SecuritySettings' +base_url: 'projects/{{project}}/locations/{{location}}/securitySettings' +update_verb: :PATCH +update_mask: true +description: | + Represents the settings related to security issues, such as data redaction and data retention. It may take hours for updates on the settings to propagate to all the related components and take effect. + Multiple security settings can be configured in each location. Each agent can specify the security settings to apply, and each setting can be applied to multiple agents in the same project and location. +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Official Documentation': 'https://cloud.google.com/dialogflow/cx/docs' + api: 'https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.securitySettings' +timeouts: !ruby/object:Api::Timeouts + insert_minutes: 40 + update_minutes: 40 +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'dialogflowcx_security_settings_basic' + primary_resource_id: 'basic_security_settings' + vars: + settings_name: 'dialogflowcx-security-settings' + - !ruby/object:Provider::Terraform::Examples + name: 'dialogflowcx_security_settings_full' + primary_resource_id: 'basic_security_settings' + vars: + inspect_name: 'dialogflowcx-inspect-template' + deidentify_name: 'dialogflowcx-deidentify-template' + settings_name: 'dialogflowcx-security-settings' + bucket_name: 'dialogflowcx-bucket' + test_env_vars: + project: :PROJECT_NAME +id_format: 'projects/{{project}}/locations/{{location}}/securitySettings/{{name}}' +import_format: ['projects/{{project}}/locations/{{location}}/securitySettings/{{name}}'] +properties: + - !ruby/object:Api::Type::String + name: 'name' + output: true + description: | + The unique identifier of the settings. + Format: projects//locations//securitySettings/. + custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb + - !ruby/object:Api::Type::String + name: 'location' + description: | + The location these settings are located in. Settings can only be applied to an agent in the same location. + See [Available Regions](https://cloud.google.com/dialogflow/cx/docs/concept/region#avail) for a list of supported locations. + required: true + immutable: true + url_param_only: true + - !ruby/object:Api::Type::String + name: 'displayName' + description: | + The human-readable name of the security settings, unique within the location. + required: true + - !ruby/object:Api::Type::Enum + name: 'redactionStrategy' + description: | + Defines how we redact data. If not set, defaults to not redacting. + * REDACT_WITH_SERVICE: Call redaction service to clean up the data to be persisted. + values: + - :REDACT_WITH_SERVICE + - !ruby/object:Api::Type::Enum + name: 'redactionScope' + description: | + Defines what types of data to redact. If not set, defaults to not redacting any kind of data. + * REDACT_DISK_STORAGE: On data to be written to disk or similar devices that are capable of holding data even if power is disconnected. This includes data that are temporarily saved on disk. + values: + - :REDACT_DISK_STORAGE + - !ruby/object:Api::Type::String + name: 'inspectTemplate' + description: | + [DLP](https://cloud.google.com/dlp/docs) inspect template name. Use this template to define inspect base settings. If empty, we use the default DLP inspect config. + Note: inspectTemplate must be located in the same region as the SecuritySettings. + Format: projects//locations//inspectTemplates/