diff --git a/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go.tmpl b/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go.tmpl index f283d995173d..b486476dd7f2 100644 --- a/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go.tmpl +++ b/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job.go.tmpl @@ -4,6 +4,7 @@ import ( "fmt" "log" "reflect" + "regexp" "strings" "time" @@ -695,14 +696,25 @@ func gcsDataSchema() *schema.Resource { }, "path": { Optional: true, - Computed: true, Type: schema.TypeString, Description: `Google Cloud Storage path in bucket to transfer`, + ValidateFunc: validatePath, }, }, } } +func validatePath(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + value = strings.TrimSpace(value) + // checks if path not started with "/" + regex, err := regexp.Compile("^/+") + if err == nil && len(value) > 0 && regex.Match([]byte(value)) { + errors = append(errors, fmt.Errorf("%q cannot start with /", k)) + } + return +} + func awsS3DataSchema() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ diff --git a/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job_test.go b/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job_test.go index 1d50924e8060..09647d6ff895 100644 --- a/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job_test.go +++ b/mmv1/third_party/terraform/services/storagetransfer/resource_storage_transfer_job_test.go @@ -573,6 +573,32 @@ func TestAccStorageTransferJob_hdfsSource(t *testing.T) { }) } +func TestAccStorageTransferJob_transferUpdateToEmptyString(t *testing.T) { + t.Parallel() + + testDataSourceBucketName := acctest.RandString(t, 10) + testDataSinkName := acctest.RandString(t, 10) + testTransferJobDescription := acctest.RandString(t, 10) + testTransferJobName := fmt.Sprintf("tf-test-transfer-job-%s", acctest.RandString(t, 10)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccStorageTransferJobDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccStorageTransferJob_transferJobGcsPath(envvar.GetTestProjectFromEnv(), testDataSourceBucketName, testDataSinkName, testTransferJobDescription, testTransferJobName, "bar/"), + }, + { + Config: testAccStorageTransferJob_transferJobGcsPath(envvar.GetTestProjectFromEnv(), testDataSourceBucketName, testDataSinkName, testTransferJobDescription, testTransferJobName, ""), + }, + { + Config: testAccStorageTransferJob_transferJobGcsPath(envvar.GetTestProjectFromEnv(), testDataSourceBucketName, testDataSinkName, testTransferJobDescription, testTransferJobName, "bar/"), + }, + }, + }) +} + func testAccStorageTransferJobDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { config := acctest.GoogleProviderConfig(t) @@ -2399,3 +2425,81 @@ resource "google_storage_transfer_job" "transfer_job" { } `, project, dataSourceBucketName, project, dataSinkBucketName, project, transferJobDescription, project) } + +func testAccStorageTransferJob_transferJobGcsPath(project string, dataSourceBucketName string, dataSinkBucketName string, transferJobDescription string, testTransferJobName string, gcsPath string) string { + return fmt.Sprintf(` + data "google_storage_transfer_project_service_account" "default" { + project = "%s" + } + + resource "google_storage_bucket" "data_source" { + name = "%s" + project = "%s" + location = "US" + force_destroy = true + uniform_bucket_level_access = true + } + + resource "google_storage_bucket_iam_member" "data_source" { + bucket = google_storage_bucket.data_source.name + role = "roles/storage.admin" + member = "serviceAccount:${data.google_storage_transfer_project_service_account.default.email}" + } + + resource "google_storage_bucket" "data_sink" { + name = "%s" + project = "%s" + location = "US" + force_destroy = true + uniform_bucket_level_access = true + } + + resource "google_storage_bucket_iam_member" "data_sink" { + bucket = google_storage_bucket.data_sink.name + role = "roles/storage.admin" + member = "serviceAccount:${data.google_storage_transfer_project_service_account.default.email}" + } + + resource "google_storage_transfer_job" "transfer_job" { + name = "transferJobs/%s" + description = "%s" + project = "%s" + + transfer_spec { + gcs_data_source { + bucket_name = google_storage_bucket.data_source.name + path = "foo/" + } + gcs_data_sink { + bucket_name = google_storage_bucket.data_sink.name + path = "%s" + } + } + + schedule { + schedule_start_date { + year = 2018 + month = 10 + day = 1 + } + schedule_end_date { + year = 2019 + month = 10 + day = 1 + } + start_time_of_day { + hours = 0 + minutes = 30 + seconds = 0 + nanos = 0 + } + repeat_interval = "604800s" + } + + depends_on = [ + google_storage_bucket_iam_member.data_source, + google_storage_bucket_iam_member.data_sink, + ] + } + `, project, dataSourceBucketName, project, dataSinkBucketName, project, testTransferJobName, transferJobDescription, project, gcsPath) +} diff --git a/mmv1/third_party/terraform/website/docs/guides/version_7_upgrade.html.markdown b/mmv1/third_party/terraform/website/docs/guides/version_7_upgrade.html.markdown index 2b7ba1125ecb..d29b27c92f4c 100644 --- a/mmv1/third_party/terraform/website/docs/guides/version_7_upgrade.html.markdown +++ b/mmv1/third_party/terraform/website/docs/guides/version_7_upgrade.html.markdown @@ -102,8 +102,8 @@ Description of the change and how users should adjust their configuration (if ne ## Resources -## Resource: `google_product_resource` +## Resource: `google_storage_transfer_job` -### Resource-level change example header +### `path` does not allow strings starting with / -Description of the change and how users should adjust their configuration (if needed). +`path` does not allow strings starting with /.