diff --git a/.changelog/17472.txt b/.changelog/17472.txt new file mode 100644 index 0000000000..dd756e5eca --- /dev/null +++ b/.changelog/17472.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +workstations: added `workstation_authorization_url` and `workstation_launch_url` fields to the `google_workstations_workstation_cluster ` resource. +``` \ No newline at end of file diff --git a/google-beta/services/workstations/resource_workstations_workstation_cluster.go b/google-beta/services/workstations/resource_workstations_workstation_cluster.go index c014254a2e..f967e09610 100644 --- a/google-beta/services/workstations/resource_workstations_workstation_cluster.go +++ b/google-beta/services/workstations/resource_workstations_workstation_cluster.go @@ -259,6 +259,19 @@ For example: "123/costCenter": "marketing"`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "workstation_authorization_url": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `Specifies the redirect URL for unauthorized requests received by workstation VMs in this cluster. +Redirects to this endpoint will send a base64 encoded 'state' query param containing the target workstation name and original request hostname. The endpoint is responsible for retrieving a token using 'GenerateAccessToken' and redirecting back to the original hostname with the token.`, + }, + "workstation_launch_url": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the launch URL for workstations in this cluster. Requests sent to unstarted workstations will be redirected to this URL. +Requests redirected to the launch endpoint will be sent with a 'workstation' query parameter containing the full workstation resource. The launch endpoint is responsible for starting the workstation, polling it until it reaches 'STATE_RUNNING', and then issuing a redirect to the workstation's host URL.`, + }, "conditions": { Type: schema.TypeList, Computed: true, @@ -387,6 +400,18 @@ func resourceWorkstationsWorkstationClusterCreate(d *schema.ResourceData, meta i } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } + workstationAuthorizationUrlProp, err := expandWorkstationsWorkstationClusterWorkstationAuthorizationUrl(d.Get("workstation_authorization_url"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("workstation_authorization_url"); !tpgresource.IsEmptyValue(reflect.ValueOf(workstationAuthorizationUrlProp)) && (ok || !reflect.DeepEqual(v, workstationAuthorizationUrlProp)) { + obj["workstationAuthorizationUrl"] = workstationAuthorizationUrlProp + } + workstationLaunchUrlProp, err := expandWorkstationsWorkstationClusterWorkstationLaunchUrl(d.Get("workstation_launch_url"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("workstation_launch_url"); !tpgresource.IsEmptyValue(reflect.ValueOf(workstationLaunchUrlProp)) && (ok || !reflect.DeepEqual(v, workstationLaunchUrlProp)) { + obj["workstationLaunchUrl"] = workstationLaunchUrlProp + } etagProp, err := expandWorkstationsWorkstationClusterEtag(d.Get("etag"), d, config) if err != nil { return err @@ -645,6 +670,18 @@ func resourceWorkstationsWorkstationClusterUpdate(d *schema.ResourceData, meta i } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } + workstationAuthorizationUrlProp, err := expandWorkstationsWorkstationClusterWorkstationAuthorizationUrl(d.Get("workstation_authorization_url"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("workstation_authorization_url"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, workstationAuthorizationUrlProp)) { + obj["workstationAuthorizationUrl"] = workstationAuthorizationUrlProp + } + workstationLaunchUrlProp, err := expandWorkstationsWorkstationClusterWorkstationLaunchUrl(d.Get("workstation_launch_url"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("workstation_launch_url"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, workstationLaunchUrlProp)) { + obj["workstationLaunchUrl"] = workstationLaunchUrlProp + } etagProp, err := expandWorkstationsWorkstationClusterEtag(d.Get("etag"), d, config) if err != nil { return err @@ -689,6 +726,14 @@ func resourceWorkstationsWorkstationClusterUpdate(d *schema.ResourceData, meta i updateMask = append(updateMask, "displayName") } + if d.HasChange("workstation_authorization_url") { + updateMask = append(updateMask, "workstationAuthorizationUrl") + } + + if d.HasChange("workstation_launch_url") { + updateMask = append(updateMask, "workstationLaunchUrl") + } + if d.HasChange("etag") { updateMask = append(updateMask, "etag") } @@ -872,6 +917,14 @@ func flattenWorkstationsWorkstationClusterDisplayName(v interface{}, d *schema.R return v } +func flattenWorkstationsWorkstationClusterWorkstationAuthorizationUrl(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenWorkstationsWorkstationClusterWorkstationLaunchUrl(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenWorkstationsWorkstationClusterDegraded(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { return v } @@ -1031,6 +1084,14 @@ func expandWorkstationsWorkstationClusterDisplayName(v interface{}, d tpgresourc return v, nil } +func expandWorkstationsWorkstationClusterWorkstationAuthorizationUrl(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandWorkstationsWorkstationClusterWorkstationLaunchUrl(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func expandWorkstationsWorkstationClusterEtag(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -1177,6 +1238,12 @@ func ResourceWorkstationsWorkstationClusterFlatten(d *schema.ResourceData, meta if err = d.Set("display_name", flattenWorkstationsWorkstationClusterDisplayName(res["displayName"], d, config)); err != nil { return fmt.Errorf("Error reading WorkstationCluster: %s", err) } + if err = d.Set("workstation_authorization_url", flattenWorkstationsWorkstationClusterWorkstationAuthorizationUrl(res["workstationAuthorizationUrl"], d, config)); err != nil { + return fmt.Errorf("Error reading WorkstationCluster: %s", err) + } + if err = d.Set("workstation_launch_url", flattenWorkstationsWorkstationClusterWorkstationLaunchUrl(res["workstationLaunchUrl"], d, config)); err != nil { + return fmt.Errorf("Error reading WorkstationCluster: %s", err) + } if err = d.Set("degraded", flattenWorkstationsWorkstationClusterDegraded(res["degraded"], d, config)); err != nil { return fmt.Errorf("Error reading WorkstationCluster: %s", err) } diff --git a/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_meta.yaml b/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_meta.yaml index 6c6f71c3b7..85dea8385c 100644 --- a/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_meta.yaml +++ b/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_meta.yaml @@ -35,7 +35,9 @@ fields: - field: terraform_labels provider_only: true - api_field: uid + - api_field: workstationAuthorizationUrl - field: workstation_cluster_id provider_only: true + - api_field: workstationLaunchUrl - field: deletion_policy provider_only: true diff --git a/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_test.go b/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_test.go index 1d3aab80aa..eec223d180 100644 --- a/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_test.go +++ b/google-beta/services/workstations/resource_workstations_workstation_cluster_generated_test.go @@ -52,6 +52,70 @@ var ( _ = workstations.Product ) +func TestAccWorkstationsWorkstationCluster_workstationClusterUrlsExample(t *testing.T) { + t.Parallel() + + randomSuffix := acctest.RandString(t, 10) + + context := map[string]interface{}{ + "cluster_id": "custom-urls-cluster", + "cluster_network_name": "tf-test-workstations-network" + randomSuffix, + "random_suffix": randomSuffix, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckWorkstationsWorkstationClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccWorkstationsWorkstationCluster_workstationClusterCustomUrlsExample(context), + }, + { + ResourceName: "google_workstations_workstation_cluster.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations", "labels", "location", "tags", "terraform_labels", "workstation_cluster_id"}, + }, + { + ResourceName: "google_workstations_workstation_cluster.default", + RefreshState: true, + ExpectNonEmptyPlan: true, + ImportStateKind: resource.ImportBlockWithResourceIdentity, + }, + }, + }) +} + +func testAccWorkstationsWorkstationCluster_workstationClusterCustomUrlsExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_workstations_workstation_cluster" "default" { + workstation_cluster_id = "%{cluster_id}" + network = google_compute_network.default.id + subnetwork = google_compute_subnetwork.default.id + location = "us-central1" + + workstation_authorization_url = "https://workstations.cloud.google.com/ui/auth" + workstation_launch_url = "https://console.cloud.google.com/workstations/launch" +} + +data "google_project" "project" { +} + +resource "google_compute_network" "default" { + name = "%{cluster_network_name}" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "default" { + name = "%{cluster_network_name}" + ip_cidr_range = "10.0.0.0/24" + region = "us-central1" + network = google_compute_network.default.name +} +`, context) +} + func TestAccWorkstationsWorkstationCluster_workstationClusterBasicExample(t *testing.T) { t.Parallel() diff --git a/website/docs/r/workstations_workstation_cluster.html.markdown b/website/docs/r/workstations_workstation_cluster.html.markdown index 9546fc3e40..dfe4513aa5 100644 --- a/website/docs/r/workstations_workstation_cluster.html.markdown +++ b/website/docs/r/workstations_workstation_cluster.html.markdown @@ -30,6 +30,40 @@ To get more information about WorkstationCluster, see: * How-to Guides * [Workstations](https://cloud.google.com/workstations/docs/) +
+ + Open in Cloud Shell + +
+## Example Usage - Workstation Cluster Custom Urls + + +```hcl +resource "google_workstations_workstation_cluster" "default" { + workstation_cluster_id = "custom-urls-cluster" + network = google_compute_network.default.id + subnetwork = google_compute_subnetwork.default.id + location = "us-central1" + + workstation_authorization_url = "https://workstations.cloud.google.com/ui/auth" + workstation_launch_url = "https://console.cloud.google.com/workstations/launch" +} + +data "google_project" "project" { +} + +resource "google_compute_network" "default" { + name = "workstations-network" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "default" { + name = "workstations-network" + ip_cidr_range = "10.0.0.0/24" + region = "us-central1" + network = google_compute_network.default.name +} +```
Open in Cloud Shell @@ -235,6 +269,16 @@ The following arguments are supported: (Optional) Human-readable name for this resource. +* `workstation_authorization_url` - + (Optional) + Specifies the redirect URL for unauthorized requests received by workstation VMs in this cluster. + Redirects to this endpoint will send a base64 encoded `state` query param containing the target workstation name and original request hostname. The endpoint is responsible for retrieving a token using `GenerateAccessToken` and redirecting back to the original hostname with the token. + +* `workstation_launch_url` - + (Optional) + Specifies the launch URL for workstations in this cluster. Requests sent to unstarted workstations will be redirected to this URL. + Requests redirected to the launch endpoint will be sent with a `workstation` query parameter containing the full workstation resource. The launch endpoint is responsible for starting the workstation, polling it until it reaches `STATE_RUNNING`, and then issuing a redirect to the workstation's host URL. + * `annotations` - (Optional) Client-specified annotations. This is distinct from labels.