From f0ac573669014c53c40fd3c6a38fa9a710c1d4d4 Mon Sep 17 00:00:00 2001 From: The Magician Date: Tue, 20 Feb 2024 10:52:07 -0800 Subject: [PATCH] Add support for custom containers for workbench instances (#9973) (#17326) * Add support for custom containers for workbench instances * Use conflicts instead of exactly_one_of for backward compatibility [upstream:aeba6c4947923df75d25ce0ec3e710b6d0140b48] Signed-off-by: Modular Magician --- .changelog/9973.txt | 3 + .../workbench/resource_workbench_instance.go | 89 +++++++++++++++++++ ...ource_workbench_instance_generated_test.go | 41 +++++++++ .../docs/r/workbench_instance.html.markdown | 37 ++++++++ 4 files changed, 170 insertions(+) create mode 100644 .changelog/9973.txt diff --git a/.changelog/9973.txt b/.changelog/9973.txt new file mode 100644 index 00000000000..2d62ba8cae4 --- /dev/null +++ b/.changelog/9973.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +workbench: added `container_image` field to `google_workbench_instance` resource +``` \ No newline at end of file diff --git a/google/services/workbench/resource_workbench_instance.go b/google/services/workbench/resource_workbench_instance.go index 79467391853..c71e8f97e9c 100644 --- a/google/services/workbench/resource_workbench_instance.go +++ b/google/services/workbench/resource_workbench_instance.go @@ -328,6 +328,28 @@ Learn more about using your own encryption keys.'`, }, }, }, + "container_image": { + Type: schema.TypeList, + Optional: true, + Description: `Use a container image to start the workbench instance.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "repository": { + Type: schema.TypeString, + Required: true, + Description: `The path to the container image repository. +For example: gcr.io/{project_id}/{imageName}`, + }, + "tag": { + Type: schema.TypeString, + Optional: true, + Description: `The tag of the container image. If not specified, this defaults to the latest tag.`, + }, + }, + }, + ConflictsWith: []string{"gce_setup.0.vm_image"}, + }, "data_disks": { Type: schema.TypeList, Computed: true, @@ -547,6 +569,7 @@ Format: {project_id}`, }, }, }, + ConflictsWith: []string{"gce_setup.0.container_image"}, }, }, }, @@ -1155,6 +1178,8 @@ func flattenWorkbenchInstanceGceSetup(v interface{}, d *schema.ResourceData, con flattenWorkbenchInstanceGceSetupServiceAccounts(original["serviceAccounts"], d, config) transformed["vm_image"] = flattenWorkbenchInstanceGceSetupVmImage(original["vmImage"], d, config) + transformed["container_image"] = + flattenWorkbenchInstanceGceSetupContainerImage(original["containerImage"], d, config) transformed["boot_disk"] = flattenWorkbenchInstanceGceSetupBootDisk(original["bootDisk"], d, config) transformed["data_disks"] = @@ -1262,6 +1287,29 @@ func flattenWorkbenchInstanceGceSetupVmImage(v interface{}, d *schema.ResourceDa return d.Get("gce_setup.0.vm_image") } +func flattenWorkbenchInstanceGceSetupContainerImage(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["repository"] = + flattenWorkbenchInstanceGceSetupContainerImageRepository(original["repository"], d, config) + transformed["tag"] = + flattenWorkbenchInstanceGceSetupContainerImageTag(original["tag"], d, config) + return []interface{}{transformed} +} +func flattenWorkbenchInstanceGceSetupContainerImageRepository(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenWorkbenchInstanceGceSetupContainerImageTag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenWorkbenchInstanceGceSetupBootDisk(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { return nil @@ -1562,6 +1610,13 @@ func expandWorkbenchInstanceGceSetup(v interface{}, d tpgresource.TerraformResou transformed["vmImage"] = transformedVmImage } + transformedContainerImage, err := expandWorkbenchInstanceGceSetupContainerImage(original["container_image"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedContainerImage); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["containerImage"] = transformedContainerImage + } + transformedBootDisk, err := expandWorkbenchInstanceGceSetupBootDisk(original["boot_disk"], d, config) if err != nil { return nil, err @@ -1787,6 +1842,40 @@ func expandWorkbenchInstanceGceSetupVmImageFamily(v interface{}, d tpgresource.T return v, nil } +func expandWorkbenchInstanceGceSetupContainerImage(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{}) + + transformedRepository, err := expandWorkbenchInstanceGceSetupContainerImageRepository(original["repository"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRepository); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["repository"] = transformedRepository + } + + transformedTag, err := expandWorkbenchInstanceGceSetupContainerImageTag(original["tag"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTag); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["tag"] = transformedTag + } + + return transformed, nil +} + +func expandWorkbenchInstanceGceSetupContainerImageRepository(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandWorkbenchInstanceGceSetupContainerImageTag(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func expandWorkbenchInstanceGceSetupBootDisk(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { diff --git a/google/services/workbench/resource_workbench_instance_generated_test.go b/google/services/workbench/resource_workbench_instance_generated_test.go index df5cbacb1a1..86bdb3d7884 100644 --- a/google/services/workbench/resource_workbench_instance_generated_test.go +++ b/google/services/workbench/resource_workbench_instance_generated_test.go @@ -65,6 +65,47 @@ resource "google_workbench_instance" "instance" { `, context) } +func TestAccWorkbenchInstance_workbenchInstanceBasicContainerExample(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: testAccCheckWorkbenchInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccWorkbenchInstance_workbenchInstanceBasicContainerExample(context), + }, + { + ResourceName: "google_workbench_instance.instance", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "instance_owners", "location", "instance_id", "labels", "terraform_labels"}, + }, + }, + }) +} + +func testAccWorkbenchInstance_workbenchInstanceBasicContainerExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_workbench_instance" "instance" { + name = "tf-test-workbench-instance%{random_suffix}" + location = "us-west1-a" + + gce_setup { + container_image { + repository = "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/base-cu113.py310" + tag = "latest" + } + } +} +`, context) +} + func TestAccWorkbenchInstance_workbenchInstanceBasicGpuExample(t *testing.T) { t.Parallel() diff --git a/website/docs/r/workbench_instance.html.markdown b/website/docs/r/workbench_instance.html.markdown index 65f4835777f..6817b67a95e 100644 --- a/website/docs/r/workbench_instance.html.markdown +++ b/website/docs/r/workbench_instance.html.markdown @@ -37,6 +37,27 @@ resource "google_workbench_instance" "instance" { location = "us-west1-a" } ``` + +## Example Usage - Workbench Instance Basic Container + + +```hcl +resource "google_workbench_instance" "instance" { + name = "workbench-instance" + location = "us-west1-a" + + gce_setup { + container_image { + repository = "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/base-cu113.py310" + tag = "latest" + } + } +} +```