Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/17472.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
workstations: added `workstation_authorization_url` and `workstation_launch_url` fields to the `google_workstations_workstation_cluster ` resource.
```
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
44 changes: 44 additions & 0 deletions website/docs/r/workstations_workstation_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,40 @@ To get more information about WorkstationCluster, see:
* How-to Guides
* [Workstations](https://cloud.google.com/workstations/docs/)

<div class = "oics-button" style="float: right; margin: 0 0 -15px">
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_image=gcr.io%2Fcloudshell-images%2Fcloudshell%3Alatest&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md&cloudshell_working_dir=workstation_cluster_custom_urls&open_in_editor=main.tf" target="_blank">
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
</a>
</div>
## 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
}
```
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_image=gcr.io%2Fcloudshell-images%2Fcloudshell%3Alatest&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md&cloudshell_working_dir=workstation_cluster_basic&open_in_editor=main.tf" target="_blank">
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
Expand Down Expand Up @@ -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.
Expand Down
Loading