From 16d4f0faa68159cdeffa19bb1cc1df810d191d73 Mon Sep 17 00:00:00 2001 From: Benjamin Kaplan <58792807+bskaplan@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:30:19 -0700 Subject: [PATCH] Add gcs volume type to Cloud Run v2 beta provider (#9746) * Add gcs volume type to Cloud Run v2 beta provider * update gcs v2 docs to specify required launch stage and execution environment * merge changes with upstream --- mmv1/products/cloudrunv2/Job.yaml | 23 ++++ mmv1/products/cloudrunv2/Service.yaml | 12 +- ... => resource_cloud_run_v2_job_test.go.erb} | 89 +++++++++++++++ .../resource_cloud_run_v2_service_test.go.erb | 103 +++++++++++++++++- 4 files changed, 224 insertions(+), 3 deletions(-) rename mmv1/third_party/terraform/services/cloudrunv2/{resource_cloud_run_v2_job_test.go => resource_cloud_run_v2_job_test.go.erb} (77%) diff --git a/mmv1/products/cloudrunv2/Job.yaml b/mmv1/products/cloudrunv2/Job.yaml index 176c056e5715..4daa40450fc6 100644 --- a/mmv1/products/cloudrunv2/Job.yaml +++ b/mmv1/products/cloudrunv2/Job.yaml @@ -399,6 +399,7 @@ properties: # - template.0.template.0.volumes.0.secret # - template.0.template.0.volumes.0.cloudSqlInstance # - template.0.template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs properties: - !ruby/object:Api::Type::String name: 'secret' @@ -437,6 +438,7 @@ properties: # - template.0.template.0.volumes.0.secret # - template.0.template.0.volumes.0.cloudSqlInstance # - template.0.template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs properties: - !ruby/object:Api::Type::Array name: 'instances' @@ -452,6 +454,7 @@ properties: # - template.0.template.0.volumes.0.secret # - template.0.template.0.volumes.0.cloudSqlInstance # - template.0.template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs properties: - !ruby/object:Api::Type::Enum name: 'medium' @@ -464,6 +467,26 @@ properties: name: 'sizeLimit' description: |- Limit on the storage usable by this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. This field's values are of the 'Quantity' k8s type: https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/. The default is nil which means that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir. + - !ruby/object:Api::Type::NestedObject + name: 'gcs' + description: |- + Cloud Storage bucket mounted as a volume using GCSFuse. This feature requires the launch stage to be set to ALPHA or BETA. + min_version: beta + # exactly_one_of: + # - template.0.volumes.0.secret + # - template.0.volumes.0.cloudSqlInstance + # - template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs + properties: + - !ruby/object:Api::Type::String + name: 'bucket' + required: true + description: |- + Name of the cloud storage bucket to back the volume. The resource service account must have permission to access the bucket. + - !ruby/object:Api::Type::Boolean + name: 'readOnly' + description: |- + If true, mount this volume as read-only in all mounts. If false, mount this volume as read-write. - !ruby/object:Api::Type::String name: 'timeout' description: |- diff --git a/mmv1/products/cloudrunv2/Service.yaml b/mmv1/products/cloudrunv2/Service.yaml index bbedcc2cf10c..909b454786a6 100644 --- a/mmv1/products/cloudrunv2/Service.yaml +++ b/mmv1/products/cloudrunv2/Service.yaml @@ -741,6 +741,7 @@ properties: # - template.0.volumes.0.secret # - template.0.volumes.0.cloudSqlInstance # - template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs properties: - !ruby/object:Api::Type::Array name: 'instances' @@ -757,6 +758,7 @@ properties: # - template.0.volumes.0.secret # - template.0.volumes.0.cloudSqlInstance # - template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs properties: - !ruby/object:Api::Type::Enum name: 'medium' @@ -770,8 +772,14 @@ properties: description: |- Limit on the storage usable by this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. This field's values are of the 'Quantity' k8s type: https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/. The default is nil which means that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir. - !ruby/object:Api::Type::NestedObject - name: gcs - description: Represents a GCS Bucket mounted as a volume. + name: 'gcs' + description: |- + Cloud Storage bucket mounted as a volume using GCSFuse. This feature is only supported in the gen2 execution environment and requires launch-stage to be set to ALPHA or BETA. + # exactly_one_of: + # - template.0.volumes.0.secret + # - template.0.volumes.0.cloudSqlInstance + # - template.0.volumes.0.emptyDir + # - template.0.volumes.0.gcs properties: - !ruby/object:Api::Type::String name: bucket 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.erb similarity index 77% rename from mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go rename to mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_job_test.go.erb index e2cbbba9a30a..feca32ee81e7 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.erb @@ -1,3 +1,4 @@ +<% autogen_exception -%> package cloudrunv2_test import ( @@ -298,3 +299,91 @@ func testAccCloudRunV2Job_cloudrunv2JobWithDirectVPCUpdate(context map[string]in } `, context) } + +<% unless version == 'ga' -%> +func TestAccCloudRunV2Job_cloudrunv2JobWithGcsUpdate(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_cloudrunv2JobWithNoVolume(context), + }, + { + ResourceName: "google_cloud_run_v2_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "launch_stage"}, + }, + { + Config: testAccCloudRunV2Job_cloudrunv2JobWithGcsVolume(context), + }, + { + ResourceName: "google_cloud_run_v2_job.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "launch_stage"}, + }, + }, + }) +} + +func testAccCloudRunV2Job_cloudrunv2JobWithNoVolume(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" + } + } + } + + lifecycle { + ignore_changes = [ + launch_stage, + ] + } + } +`, context) +} + +func testAccCloudRunV2Job_cloudrunv2JobWithGcsVolume(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" + volume_mounts { + name = "gcs" + mount_path = "/mnt/gcs" + } + } + volumes { + name = "gcs" + gcs { + bucket = "gcp-public-data-landsat" + read_only = true + } + } + } + } + } +`, context) +} +<% end -%> diff --git a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go.erb b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go.erb index bacaa401b2d6..b4f3b6ad5a9a 100644 --- a/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go.erb +++ b/mmv1/third_party/terraform/services/cloudrunv2/resource_cloud_run_v2_service_test.go.erb @@ -46,6 +46,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { }) } + func testAccCloudRunV2Service_cloudrunv2ServiceFull(context map[string]interface{}) string { return acctest.Nprintf(` resource "google_cloud_run_v2_service" "default" { @@ -109,7 +110,6 @@ resource "google_service_account" "service_account" { } `, context) } - func testAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(context map[string]interface{}) string { return acctest.Nprintf(` resource "google_cloud_run_v2_service" "default" { @@ -208,7 +208,108 @@ resource "google_compute_network" "custom_test" { } `, context) } +<% unless version == 'ga' -%> +func TestAccCloudRunV2Service_cloudrunv2ServiceGcsVolume(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: testAccCheckCloudRunV2ServiceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudRunV2Service_cloudrunv2ServiceGcsVolume(context), + }, + { + ResourceName: "google_cloud_run_v2_service.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations", "labels", "terraform_labels", "launch_stage"}, + }, + }, + }) +} + +func testAccCloudRunV2Service_cloudrunv2ServiceGcsVolume(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_cloud_run_v2_service" "default" { + name = "tf-test-cloudrun-service%{random_suffix}" + description = "description creating" + location = "us-central1" + launch_stage = "BETA" + annotations = { + generated-by = "magic-modules" + } + ingress = "INGRESS_TRAFFIC_ALL" + labels = { + label-1 = "value-1" + } + client = "client-1" + client_version = "client-version-1" + template { + labels = { + label-1 = "value-1" + } + timeout = "300s" + service_account = google_service_account.service_account.email + execution_environment = "EXECUTION_ENVIRONMENT_GEN2" + scaling { + max_instance_count = 3 + min_instance_count = 1 + } + annotations = { + generated-by = "magic-modules" + } + volumes { + name = "gcs" + gcs { + bucket = "gcp-public-data-landsat" + read_only = true + } + } + containers { + name = "container-1" + image = "us-docker.pkg.dev/cloudrun/container/hello" + env { + name = "SOURCE" + value = "remote" + } + env { + name = "TARGET" + value = "home" + } + ports { + name = "h2c" + container_port = 8080 + } + volume_mounts { + name = "gcs" + mount_path = "/mnt/landsat" + } + resources { + cpu_idle = true + startup_cpu_boost = true + limits = { + cpu = "4" + memory = "2Gi" + } + } + } + session_affinity = false + } +} +resource "google_service_account" "service_account" { + account_id = "tf-test-my-account%{random_suffix}" + display_name = "Test Service Account" +} +`, context) +} +<%end -%> func TestAccCloudRunV2Service_cloudrunv2ServiceTCPProbesUpdate(t *testing.T) { t.Parallel()